mod-build 4.0.0-alpha.2 → 4.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintignore CHANGED
@@ -1,3 +1,5 @@
1
1
  src/scripts/vendor/**/*.js
2
2
  src/resources/scripts/**/*.js
3
- src/compiled/**/*.js
3
+ src/compiled/**/*.js
4
+ src/accessible-components/**/*.js
5
+ src/shared-components/**/*.js
package/main.js ADDED
@@ -0,0 +1 @@
1
+ import './src/styles/home.scss';
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "mod-build",
3
- "version": "4.0.0-alpha.2",
3
+ "version": "4.0.0-alpha.20",
4
4
  "description": "Share components for S3 sites.",
5
5
  "type": "module",
6
6
  "scripts": {
7
- "dev": "export NODE_ENV=qa.modernize.com IS_LOCAL=true && vite",
8
- "build": "vite build",
9
- "preview": "vite preview"
7
+ "dev": "export NODE_ENV=modernize.com IS_LOCAL=true && vite",
8
+ "build": "export NODE_ENV=modernize.com && vite build",
9
+ "preview": "export NODE_ENV=modernize.com && vite preview"
10
10
  },
11
11
  "dependencies": {
12
12
  "@rollup/plugin-inject": "^5.0.5",
13
+ "@vituum/vite-plugin-handlebars": "^1.1.0",
13
14
  "axios": "^1.6.2",
14
15
  "del": "^7.1.0",
15
16
  "eslint": "^8.55.0",
@@ -19,11 +20,11 @@
19
20
  "gulp-replace": "^1.1.4",
20
21
  "gulp-tap": "^2.0.0",
21
22
  "husky": "^8.0.3",
22
- "jquery": "^3.7.1",
23
+ "lodash.merge": "^4.6.2",
23
24
  "sass": "^1.69.5",
24
25
  "vite": "^5.0.0",
25
26
  "vite-plugin-eslint": "^1.8.1",
26
- "vite-plugin-handlebars": "^1.6.0",
27
- "vite-plugin-static-copy": "^1.0.0"
27
+ "vite-plugin-static-copy": "^1.0.0",
28
+ "vituum": "^1.1.0"
28
29
  }
29
30
  }
@@ -0,0 +1,4 @@
1
+ <svg width="245" height="45" viewBox="0 0 245 45" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M74.94 27.036C74.628 27.504 74.2467 27.946 73.796 28.362C73.3627 28.778 72.8513 29.142 72.262 29.454C71.69 29.766 71.0487 30.0087 70.338 30.182C69.6447 30.3727 68.882 30.468 68.05 30.468C66.6633 30.468 65.3807 30.2253 64.202 29.74C63.0233 29.2547 62.0093 28.5873 61.16 27.738C60.3107 26.8713 59.6433 25.8487 59.158 24.67C58.69 23.4913 58.456 22.2 58.456 20.796C58.456 19.392 58.6987 18.1007 59.184 16.922C59.6693 15.7433 60.3367 14.7293 61.186 13.88C62.0527 13.0133 63.0667 12.3373 64.228 11.852C65.4067 11.3667 66.6807 11.124 68.05 11.124C68.726 11.124 69.3847 11.1933 70.026 11.332C70.6847 11.4707 71.3 11.67 71.872 11.93C72.444 12.1727 72.964 12.476 73.432 12.84C73.9 13.1867 74.29 13.5853 74.602 14.036L73.042 15.18C72.8513 14.8853 72.5913 14.5907 72.262 14.296C71.95 14.0013 71.5773 13.7413 71.144 13.516C70.7107 13.2907 70.234 13.1087 69.714 12.97C69.2113 12.8313 68.6653 12.762 68.076 12.762C66.88 12.762 65.8053 12.9787 64.852 13.412C63.916 13.8453 63.1187 14.4347 62.46 15.18C61.8013 15.908 61.2987 16.7573 60.952 17.728C60.6053 18.6987 60.432 19.7213 60.432 20.796C60.432 21.8707 60.6053 22.8933 60.952 23.864C61.316 24.8347 61.8273 25.6927 62.486 26.438C63.1447 27.166 63.942 27.7467 64.878 28.18C65.8313 28.6133 66.8973 28.83 68.076 28.83C69.1333 28.83 70.1387 28.6133 71.092 28.18C72.0453 27.7467 72.8427 27.0533 73.484 26.1L74.94 27.036ZM91.4242 23.058C91.4242 24.1153 91.2335 25.086 90.8522 25.97C90.4882 26.854 89.9769 27.6167 89.3182 28.258C88.6769 28.8993 87.9055 29.402 87.0042 29.766C86.1202 30.13 85.1582 30.312 84.1182 30.312C83.0782 30.312 82.1162 30.13 81.2322 29.766C80.3482 29.402 79.5769 28.8993 78.9182 28.258C78.2769 27.6167 77.7742 26.854 77.4102 25.97C77.0462 25.086 76.8642 24.1153 76.8642 23.058C76.8642 22.0007 77.0462 21.03 77.4102 20.146C77.7742 19.262 78.2769 18.508 78.9182 17.884C79.5769 17.2427 80.3482 16.7487 81.2322 16.402C82.1162 16.0553 83.0782 15.882 84.1182 15.882C85.1582 15.882 86.1202 16.0553 87.0042 16.402C87.9055 16.7487 88.6769 17.2427 89.3182 17.884C89.9769 18.508 90.4882 19.262 90.8522 20.146C91.2335 21.03 91.4242 22.0007 91.4242 23.058ZM89.4482 23.058C89.4482 22.2953 89.3182 21.576 89.0582 20.9C88.8155 20.224 88.4602 19.6347 87.9922 19.132C87.5415 18.612 86.9869 18.2047 86.3282 17.91C85.6695 17.6153 84.9329 17.468 84.1182 17.468C83.3035 17.468 82.5669 17.6153 81.9082 17.91C81.2669 18.2047 80.7122 18.612 80.2442 19.132C79.7935 19.6347 79.4469 20.224 79.2042 20.9C78.9615 21.576 78.8402 22.2953 78.8402 23.058C78.8402 23.8207 78.9615 24.5487 79.2042 25.242C79.4642 25.918 79.8195 26.516 80.2702 27.036C80.7209 27.5387 81.2669 27.9373 81.9082 28.232C82.5669 28.5267 83.3035 28.674 84.1182 28.674C84.9329 28.674 85.6695 28.5267 86.3282 28.232C86.9869 27.9373 87.5415 27.5387 87.9922 27.036C88.4602 26.516 88.8155 25.918 89.0582 25.242C89.3182 24.5487 89.4482 23.8207 89.4482 23.058ZM102.315 26.958H102.367L106.527 16.194H109.361V30H107.541V18.378H107.489L102.835 30H101.717L97.063 18.378H97.037V30H95.217V16.194H98.077L102.315 26.958ZM114.031 16.194H118.321C119.795 16.194 120.973 16.5407 121.857 17.234C122.741 17.91 123.183 18.924 123.183 20.276C123.183 20.952 123.053 21.55 122.793 22.07C122.551 22.5727 122.204 22.9973 121.753 23.344C121.32 23.6907 120.8 23.9507 120.193 24.124C119.587 24.2973 118.928 24.384 118.217 24.384H115.851V30H114.031V16.194ZM115.851 22.85H118.113C119.084 22.85 119.864 22.642 120.453 22.226C121.043 21.7927 121.337 21.1427 121.337 20.276C121.337 19.392 121.034 18.7593 120.427 18.378C119.838 17.9967 119.067 17.806 118.113 17.806H115.851V22.85ZM125.502 30H123.578L129.532 16.194H131.222L137.15 30H135.096L133.666 26.542H126.958L125.502 30ZM127.608 24.956H133.016L130.338 18.3L127.608 24.956ZM149.037 27.348H149.089V16.194H150.909V30H148.621L141.497 18.612H141.471V30H139.651V16.194H142.017L149.037 27.348ZM160.224 30H158.404V24.02L153.256 16.194H155.44L159.34 22.512L163.24 16.194H165.424L160.224 24.02V30ZM185.516 30L178.106 17.962H178.028L178.132 30H173.816V11.592H178.886L186.27 23.604H186.348L186.244 11.592H190.56V30H185.516ZM198.569 15.362H203.093L209.177 30H204.471L203.483 27.348H198.023L197.009 30H192.407L198.569 15.362ZM200.753 19.756L199.089 24.228H202.391L200.753 19.756ZM215.095 21.004H215.017L215.095 30H210.935V15.362H216.785L219.671 23.89H219.775L222.531 15.362H228.329V30H224.039L224.117 21.004H224.039L221.049 30H218.007L215.095 21.004ZM231.959 15.362H242.333V18.664H236.197V21.004H241.995V24.176H236.197V26.672H242.697V30H231.959V15.362Z" fill="#212021"/>
3
+ <rect width="45" height="45" rx="22.5" fill="#DCDCDC"/>
4
+ </svg>
package/siteconfig.js CHANGED
@@ -1,38 +1,23 @@
1
- export let siteData = {
2
- primary_trade: 'Medical Alerts',
3
- service: 'alerts_medical', // required to fetch the correct tcpa blurb
4
- gtm_container_ID: 'GTM-TBJV3H', // e.g. GTM-N23VMDW
5
- qs_gtm_container_ID: 'GTM-TBJV3H',
6
- email: 'support@emedicalalerts.com', // e.g. // e.g. support@homesolarsurvey.com
7
- email_unsub: 'unsubscribe@emedicalalerts.com', // e.g. unsubscribe@homesolarsurvey.com
8
- domain: 'emedicalalerts.com', // e.g. homesolarsurvey.com
9
- company_name: 'eMedicalAlerts', // e.g. Home Solar Survey
10
- website_name: 'eMedicalAlerts.com', // e.g. HomeSolarSurvey.com
11
- useCDN: true,
12
- isWhiteLabel: true,
13
- isQSPage: true,
14
- useAccessibleConfig: true
1
+ /**
2
+ * Site-specific information that can be used
3
+ * inside HTML template using Handlebars
4
+ */
5
+ export let siteData = () => {
6
+ return {
7
+ primary_trade: 'Home Warranty',
8
+ service: 'home_warranty',
9
+ gtm_container_ID: 'GTM-PZGPJR6',
10
+ qs_gtm_container_ID: 'GTM-PZGPJR6',
11
+ email: 'support@bestcompany.com',
12
+ email_unsub: 'unsubscribe@bestcompany.com',
13
+ domain: 'bestcompany.com',
14
+ company_name: 'BestCompany',
15
+ website_name: 'BestCompany.com',
16
+ useCDN: true,
17
+ isWhiteLabel: true,
18
+ isQSPage: true,
19
+ useAccessibleConfig: true,
20
+ isVite: true,
21
+ pathSubdirectory: 'src/'
22
+ };
15
23
  };
16
-
17
- export function setSiteData(newSiteData) {
18
- siteData = newSiteData;
19
- }
20
-
21
- export const defaultSettings = {
22
- tmpFolder: '.tmp',
23
- srcFolder: 'src',
24
- browserSyncServeFolders: ['.tmp', 'src', 'node_modules/mod-style-bootstrap/src', 'node_modules/mod-base/src'],
25
- distFolder: 'dist',
26
- fontsSubfolder: 'fonts',
27
- imagesSubfolder: 'images',
28
- stylesSubfolder: 'styles',
29
- scriptsSubfolder: 'scripts',
30
- scriptsCompiledFolder: 'scripts/compiled',
31
- templatesSubfolder: 'templates',
32
- dataSubfolder: 'data',
33
- modBuild: '',
34
- resourceDomain: process.env.IS_LOCAL ? 'qa.modernize.com' : 'modernize.com',
35
- nodeEnv: process.env.NODE_ENV,
36
- isLocal: process.env.IS_LOCAL || import.meta?.env?.DEV,
37
- buildPath: process.env.BUILD_PATH
38
- }
@@ -0,0 +1,16 @@
1
+ export const defaultSettings = {
2
+ tmpFolder: '.tmp',
3
+ srcFolder: 'src',
4
+ distFolder: 'dist',
5
+ fontsSubfolder: 'fonts',
6
+ imagesSubfolder: 'images',
7
+ stylesSubfolder: 'styles',
8
+ scriptsSubfolder: 'scripts',
9
+ scriptsCompiledFolder: 'scripts/compiled',
10
+ templatesSubfolder: 'templates',
11
+ dataSubfolder: 'data',
12
+ modBuild: '',
13
+ nodeEnv: process.env.NODE_ENV,
14
+ isLocal: process.env.IS_LOCAL || import.meta?.env?.DEV,
15
+ buildPath: process.env.BUILD_PATH
16
+ }
@@ -1,5 +1,7 @@
1
1
  /* contains data for qs-footer and quote-footer */
2
2
  export default function(siteData) {
3
+ const { isQSPage } = siteData;
4
+
3
5
  let trade = '';
4
6
  if (siteData?.contractor_trade) {
5
7
  trade = `&trade=${siteData.contractor_trade}`;
@@ -7,7 +9,7 @@ export default function(siteData) {
7
9
  trade = `&trade=${siteData.primary_trade.replace(/[\s]+|_/g, '-').toLowerCase()}`;
8
10
  }
9
11
 
10
- const footerKey = siteData.isQSPage ? 'qsFooterData' : 'quoteFooterData';
12
+ const footerKey = isQSPage ? 'qsFooterData' : 'quoteFooterData';
11
13
 
12
14
  const qsLinks = [
13
15
  {
@@ -101,15 +103,15 @@ export default function(siteData) {
101
103
  const data = {
102
104
  [footerKey]: {
103
105
  links: [
104
- ...siteData.isQSPage ? qsLinks : quoteLinks,
106
+ isQSPage ? qsLinks : quoteLinks,
105
107
  ],
106
- copyright: `${siteData.isQSPage ? 'QuinStreet, Inc.' : ''} All&nbsp;Rights&nbsp;Reserved.`,
108
+ copyright: `${isQSPage ? 'QuinStreet, Inc.' : ''} All&nbsp;Rights&nbsp;Reserved.`,
107
109
  contractor: {
108
110
  text: 'Are you a contractor?',
109
111
  linkText: 'Join Our Contractor Network',
110
112
  link: 'https://modernize.com/pro/register/leads/?utm_campaign=quinstreet-referral' + trade
111
113
  },
112
- ...siteData.isQSPage ? null : quoteSpecific,
114
+ ...isQSPage ? null : quoteSpecific,
113
115
  }
114
116
  }
115
117
 
@@ -4,15 +4,15 @@
4
4
  {{ fileInclude 'src/templates/components/head.html'
5
5
  page = this
6
6
  path = 'home'
7
- }}
8
- </head>
7
+ }}
8
+ </head>
9
9
  <body>
10
+ {{ log this }}
10
11
  {{#header}}
11
- {{ fileInclude 'src/accessible-components/header/header.html'
12
- header = this
13
- }}
14
- {{/header}}
15
- <h1>Hello</h1>
12
+ {{ fileInclude 'src/accessible-components/header/header.html'
13
+ header = this
14
+ }}
15
+ {{/header}}
16
16
  <script type="module" src="/main.js"></script>
17
17
  </body>
18
18
  </html>
@@ -0,0 +1,36 @@
1
+ export const loadAdditionalAssets = (config) => {
2
+ const { page } = config;
3
+ const { additionalAssets } = page.headConfig;
4
+
5
+ if (additionalAssets) {
6
+ const { afterBegin, beforeEnd } = additionalAssets;
7
+
8
+ if (afterBegin || beforeEnd) {
9
+ let additionalHeadAssets = [];
10
+ if (afterBegin) {
11
+ additionalHeadAssets.push(...afterBegin);
12
+ }
13
+ if (beforeEnd) {
14
+ additionalHeadAssets.push(...beforeEnd);
15
+ }
16
+
17
+ additionalHeadAssets.forEach((asset) => {
18
+ const { type, src, isLocal, localSrc, useModCdn, defer, async } = asset;
19
+ if (type === 'script') {
20
+ const script = document.createElement(type);
21
+ script.src = (isLocal ? localSrc : (useModCdn ? `https://${config.nodeEnv}/${src}` : src));
22
+ script.async = async;
23
+ script.defer = defer;
24
+ document.head.appendChild(script);
25
+ }
26
+
27
+ if (type === 'style') {
28
+ const link = document.createElement('link');
29
+ link.rel = 'stylesheet';
30
+ link.href = (isLocal ? localSrc : (useModCdn ? `https://${config.nodeEnv}/${src}` : src));
31
+ document.head.appendChild(link);
32
+ }
33
+ });
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,11 @@
1
+
2
+ export const useDynamicGtm = (config) => {
3
+ const { page } = config;
4
+
5
+ if (page.headConfig.useDynamicGtm || typeof window.isQSPage === 'undefined') {
6
+ import('@/scripts/has-qs-params.js').then((qs) => {
7
+ qs.default();
8
+ window.gtm_container_ID = window.isQSPage ? config.qs_gtm_container_ID : config.gtm_container_ID;
9
+ });
10
+ }
11
+ }
@@ -1,5 +1,5 @@
1
+ import fs from "node:fs";
1
2
  import { seasons } from "../data/seasons.js";
2
- import { defaultSettings } from "../../siteconfig.js";
3
3
  import gulpHandlebarsFileInclude from "gulp-handlebars-file-include";
4
4
 
5
5
  export function getFileFromURL(url) {
@@ -30,7 +30,7 @@ export function getActiveSeasons() {
30
30
  function handlebarsX(expression, context) {
31
31
  const result = (function() {
32
32
  try {
33
- return new Function(expression);
33
+ return eval(expression);
34
34
  }
35
35
  catch (e) {
36
36
  console.warn(
@@ -45,7 +45,7 @@ function handlebarsX(expression, context) {
45
45
  return result;
46
46
  }
47
47
 
48
- export const handlebarsHelpers = [
48
+ const handlebarsHelpers = [
49
49
  // Run any js line
50
50
  {
51
51
  name: 'x',
@@ -140,39 +140,65 @@ export const handlebarsHelpers = [
140
140
  fn: function(obj) {
141
141
  var output = '';
142
142
  var ignoreKeys = Array.prototype.slice.call(arguments, 1, -1);
143
-
144
- for (var key in obj.attributes) {
145
- if (ignoreKeys.indexOf(key) === -1) {
146
- if (typeof obj.attributes[key] !== 'object') {
147
- output += key + '="' + obj.attributes[key] + '" ';
148
- } else if (key === 'data') {
149
- for (var dataKey in obj.attributes[key]) {
150
- output += 'data-' + dataKey + '="' + obj.attributes[key][dataKey] + '" ';
151
- }
152
- } else if (key === 'aria') {
153
- for (var ariaKey in obj.attributes[key]) {
154
- output += 'aria-' + ariaKey + '="' + obj.attributes[key][ariaKey] + '" ';
155
- }
156
- }
143
+ if (obj && typeof obj.attributes === 'object') {
144
+ for (var key in obj.attributes) {
145
+ if (ignoreKeys.indexOf(key) === -1) {
146
+ if (typeof obj.attributes[key] !== 'object') {
147
+ output += key + '="' + obj.attributes[key] + '" ';
148
+ } else if (key === 'data') {
149
+ for (var dataKey in obj.attributes[key]) {
150
+ output += 'data-' + dataKey + '="' + obj.attributes[key][dataKey] + '" ';
151
+ }
152
+ } else if (key === 'aria') {
153
+ for (var ariaKey in obj.attributes[key]) {
154
+ output += 'aria-' + ariaKey + '="' + obj.attributes[key][ariaKey] + '" ';
155
+ }
156
+ }
157
+ }
157
158
  }
158
159
  }
159
160
  return output.trim();
160
161
  }
161
162
  },
162
- {
163
- name: 'resolveAlias',
164
- fn: function(input) {
165
- if (input.includes('@')) {
166
- const resolvedValue = defaultSettings.modBuild || '';
167
- return input.replace('@', resolvedValue);
168
- }
169
- return input;
170
- }
171
- },
172
163
  {
173
164
  name: 'fileInclude',
174
165
  fn: function(input) {
175
166
  return gulpHandlebarsFileInclude(input);
176
167
  }
177
168
  }
178
- ]
169
+ ]
170
+
171
+ export const updateConfig = (config) => {
172
+ let mergedConfig = { ...config };
173
+
174
+ return {
175
+ name: 'update-config',
176
+ configResolved({ configFileDependencies }) {
177
+ configFileDependencies.forEach((file) => {
178
+ if (file.endsWith('siteconfig.js') || file.endsWith('template.js')) {
179
+ console.log('siteconfig or template changed');
180
+ try {
181
+ const configData = fs.readFileSync('src/.tmp/config.json', 'utf8');
182
+ const parsedConfig = JSON.parse(configData);
183
+
184
+ mergedConfig = {
185
+ ...parsedConfig,
186
+ ...mergedConfig,
187
+ };
188
+
189
+ // overwrite the config file with new data
190
+ fs.writeFileSync('src/.tmp/config.json', JSON.stringify(mergedConfig, null, 2));
191
+ } catch (error) {
192
+ console.error(`Error reading config file: ${error}`);
193
+ }
194
+ }
195
+ });
196
+ },
197
+ configureServer() {
198
+ gulpHandlebarsFileInclude(mergedConfig, { handlebarsHelpers, maxRecursion: 500 });
199
+ },
200
+ buildEnd() {
201
+ gulpHandlebarsFileInclude(mergedConfig, { handlebarsHelpers, maxRecursion: 500 });
202
+ }
203
+ }
204
+ }
@@ -0,0 +1,5 @@
1
+ import './google-tag-manager-head.js'
2
+ import './heap-addeventproperties-identify.js'
3
+ import './heap-tracking.js'
4
+ import './heap-vwo.js'
5
+ import './visual-website-optimizer.js'
@@ -0,0 +1,9 @@
1
+ @import "_contact-us.scss";
2
+ @import "_google-address-autocomplete.scss";
3
+ @import "_mixins.scss";
4
+ @import "_modal-pages.scss";
5
+ @import "_modernize-colors.scss";
6
+ @import "_qs-footer.scss";
7
+ @import "_quote-footer-v1.scss";
8
+ @import "_quote-footer-v2.scss";
9
+ @import "_quote-footer-v3.scss";
@@ -1,20 +1,16 @@
1
1
  <!-- an example of the head component for v4.0.0 -->
2
2
  <meta charset="UTF-8" />
3
- <link rel="icon" type="image/svg+xml" href="/{{#if page.headConfig.faviconPath}}{{page.headConfig.faviconPath}}{{else}}favicon.svg"{{/if}} />
3
+ <link rel="icon" type="image/svg+xml" href="{{#if page.headConfig.faviconPath}}{{page.headConfig.faviconPath}}{{else}}favicon.svg"{{/if}} />
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
5
 
6
- <!-- assets links afterBegin -->
7
- {{#if page.headConfig.useModAnalytics}}
8
- <script src="https://{{this.resourceDomain}}/quote/resources/mod-alytics/modalytics.min.js" {{#if page.headConfig.deferModAnalytics}}defer{{/if}} {{#if page.headConfig.asyncModAnalytics}}async{{/if}}></script>
6
+ {{#if this.page.headConfig.useModAnalytics}}
7
+ <script src="https://{{this.page.nodeEnv}}/quote/resources/mod-alytics/modalytics.min.js" {{#if page.headConfig.deferModAnalytics}}defer{{/if}} {{#if page.headConfig.asyncModAnalytics}}async{{/if}}></script>
9
8
  {{/if}}
10
-
11
- <!-- Include vwo setup -->
12
- {{#xif "this.page.headConfig.vwoSetup.vwoPathArray.indexOf(this.path) > -1" }}
9
+ {{#xif "this.page.headConfig.vwoSetup.vwoPathArray.includes(this.path)" }}
13
10
  <link rel="preconnect" href="https://dev.visualwebsiteoptimizer.com">
14
- <!-- Do not double hit our analytical resources (Heap/Google Analytics) if the page is going to be redirected by a VWO a/b test-->
15
- <script src="{{ resolveAlias '@/scripts/vendor/visual-website-optimizer.js'}}"></script>
11
+ <script type="module" src="../scripts/vendor/visual-website-optimizer.js"></script>
16
12
  {{else}}
17
- <script src="{{ resolveAlias '@/scripts/url-cleaner.js'}}"></script>
13
+ <script type="module" src="../scripts/url-cleaner.js'"></script>
18
14
  {{/xif}}
19
15
 
20
16
  {{#unless page.headConfig.disableRobots}}
@@ -48,13 +44,13 @@
48
44
 
49
45
  <!-- site title -->
50
46
  <title>
51
- {{#if page.headConfig.inverseTitle}}
47
+ {{#if this.headConfig.inverseTitle}}
52
48
  {{#unless page.headConfig.hideTitleCompanyName}}{{company_name}} | {{/unless}}
53
49
  {{#if this.pageTitle}}
54
50
  {{this.pageTitle}}
55
51
  {{else}}
56
52
  {{#if page.headConfig.title}}
57
- {{page.headConfig.title}}
53
+ {{this.headConfig.title}}
58
54
  {{/if}}
59
55
  {{/if}}
60
56
  {{else}}
package/tasks/clean.js CHANGED
@@ -1,10 +1,9 @@
1
1
  import { deleteSync } from 'del';
2
- import { defaultSettings } from '../siteconfig';
2
+ import { defaultSettings } from '../src/data/config.js';
3
3
 
4
4
  const clean = (done) => {
5
5
  deleteSync([
6
- `src/${defaultSettings.tmpFolder}/`,
7
- `${defaultSettings.distFolder}/`
6
+ `src/${defaultSettings.tmpFolder}/`
8
7
  ]);
9
8
  console.log('clean finished');
10
9
  done();
package/tasks/grab-cdn.js CHANGED
@@ -1,14 +1,32 @@
1
- import { defaultSettings, siteData } from '../siteconfig.js'
2
- import { templateData } from '../template.js';
1
+ import { defaultSettings } from '../src/data/config.js';
3
2
  import axios from 'axios';
4
3
  import { createWriteStream } from 'node:fs';
5
4
  import * as stream from 'node:stream';
6
5
  import { promisify } from 'node:util';
7
6
  import fs from 'node:fs';
7
+ import path from 'node:path';
8
+
9
+ async function duplicateHtmlFiles(externalResources) {
10
+ for (const inputPath in externalResources) {
11
+ const [destPath, fileName] = externalResources[inputPath];
12
+ const fileExtension = path.extname(fileName);
13
+
14
+ if (fileExtension === '.html') {
15
+ const newFileName = fileName.replace('.html', '.hbs');
16
+ const sourceFilePath = path.join('src', destPath, fileName);
17
+ const destinationFilePath = path.join('src', destPath, newFileName);
18
+
19
+ if (fs.existsSync(sourceFilePath) && !fs.existsSync(destinationFilePath)) {
20
+ fs.copyFileSync(sourceFilePath, destinationFilePath);
21
+ console.log(`${sourceFilePath} duplicated as ${destinationFilePath}`);
22
+ }
23
+ }
24
+ }
25
+ }
8
26
 
9
27
  function streamToDestination(inputPath, destPath, fileName) {
10
28
  const finished = promisify(stream.finished);
11
- const url = `https://${defaultSettings.resourceDomain}${inputPath}`;
29
+ const url = `https://${defaultSettings.nodeEnv}${inputPath}`;
12
30
 
13
31
  return new Promise(resolve => {
14
32
  if (!fs.existsSync(`src/${destPath}`)) {
@@ -44,11 +62,10 @@ function streamToDestination(inputPath, destPath, fileName) {
44
62
  });
45
63
  }
46
64
 
47
- export default async function(done) {
65
+ export default async function(config) {
48
66
  const { nodeEnv, isLocal } = defaultSettings;
49
- const { isQSPage, isWhiteLabel, domain } = siteData;
50
- const { page } = templateData();
51
- const { themeFile } = page;
67
+ const { isQSPage, isWhiteLabel, domain, page } = config;
68
+ const { themeFile, cssThemes } = page;
52
69
  const isModWhiteLabel = isWhiteLabel && !isQSPage
53
70
  const domainHasModernize = domain.indexOf('modernize') > -1;
54
71
 
@@ -75,13 +92,21 @@ export default async function(done) {
75
92
  Object.assign(externalResources, {'/quote/resources/mod-site/templates/scripts/recaptcha.html': ['/templates/scripts/', 'recaptcha.html']});
76
93
  }
77
94
 
95
+ if (cssThemes && cssThemes.length > 0) {
96
+ cssThemes.forEach(theme => {
97
+ const themeFileName = `_${theme}.scss`;
98
+ const themePath = `/quote/resources/shared-resources/styles/themes/${themeFileName}`;
99
+ Object.assign(externalResources, {[themePath]: ['/resources/styles/themes/', themeFileName]});
100
+ });
101
+ }
102
+
78
103
  // local dev files
79
104
  const remoteFilesForLocalDev = {
80
105
  '/quote/resources/mod-site/scripts/vendor/maxmind-geoip2.js': ['/temp/scripts/', 'maxmind-geoip2.js']
81
106
  };
82
107
 
83
108
  // theme JSON
84
- if (isQSPage) {
109
+ if (isQSPage && themeFile) {
85
110
  Object.assign(externalResources, {
86
111
  [`/quote/resources/data/themes/${themeFile}.json`]: ['/data/', 'theme.json']
87
112
  });
@@ -103,5 +128,5 @@ export default async function(done) {
103
128
  });
104
129
 
105
130
  await Promise.all(filesPromiseMap);
106
- done();
107
- };
131
+ await duplicateHtmlFiles(externalResources);
132
+ }
@@ -1,4 +1,4 @@
1
- import { defaultSettings } from '../siteconfig.js'
1
+ import { defaultSettings } from '../src/data/config.js';
2
2
  import axios from 'axios';
3
3
  import { createWriteStream } from 'node:fs';
4
4
  import * as stream from 'node:stream';
@@ -14,7 +14,7 @@ const streamToDestination = (destPath, fileName) => {
14
14
  }
15
15
 
16
16
  const finished = promisify(stream.finished);
17
- const url = `https://${defaultSettings.resourceDomain}/${resourcePath}/${fileName}`;
17
+ const url = `https://${defaultSettings.nodeEnv}/${resourcePath}/${fileName}`;
18
18
 
19
19
  return new Promise(resolve => {
20
20
  const folderPath = `${defaultSettings.srcFolder}/${destPath}`;
@@ -55,13 +55,13 @@ async function getHelpers() {
55
55
  let helpers = [];
56
56
  await new Promise(resolve => {
57
57
  const options = {
58
- url: `https://${defaultSettings.resourceDomain}/${resourcePath}/chunks.txt`,
58
+ url: `https://${defaultSettings.nodeEnv}/${resourcePath}/chunks.txt`,
59
59
  method: 'get'
60
60
  }
61
61
 
62
62
  axios(options).then(resp => {
63
63
  if (resp.status !== 200) {
64
- throw new Error(`${resp.status}: Error while fetching ${url}`);
64
+ throw new Error(`${resp.status}: Error while fetching ${options.url}`);
65
65
  }
66
66
  helpers = resp.data.split('\n');
67
67
  resolve();
@@ -76,7 +76,7 @@ async function getHelpers() {
76
76
  return helpers;
77
77
  }
78
78
 
79
- export default async function(done) {
79
+ export default async function() {
80
80
  const { nodeEnv } = defaultSettings;
81
81
  const helpers = await getHelpers(defaultSettings);
82
82
 
@@ -86,9 +86,11 @@ export default async function(done) {
86
86
  const destinationPath = '/resources/scripts/helpers/';
87
87
  const filesPromiseMap = helpers.map(async helper => {
88
88
  const fileName = helper;
89
+ if (fs.existsSync(`${defaultSettings.srcFolder}/${destinationPath}/${fileName}`)) {
90
+ return;
91
+ }
89
92
  await streamToDestination(destinationPath, fileName);
90
93
  });
91
94
 
92
95
  await Promise.all(filesPromiseMap);
93
- done();
94
96
  }
@@ -1,4 +1,4 @@
1
- import { defaultSettings, siteData } from '../siteconfig.js'
1
+ import { defaultSettings } from '../src/data/config.js'
2
2
  import axios from 'axios';
3
3
  import { createWriteStream } from 'node:fs';
4
4
  import * as stream from 'node:stream';
@@ -6,7 +6,6 @@ import { promisify } from 'node:util';
6
6
  import fs from 'node:fs';
7
7
 
8
8
  const resourcePath = 'quote/resources/mod-site';
9
- const componentFolders = ['accessible-components'];
10
9
 
11
10
  const streamSharedCompsToDestination = (defaultSettings, folder, fileName) => {
12
11
  const finished = promisify(stream.finished);
@@ -15,10 +14,6 @@ const streamSharedCompsToDestination = (defaultSettings, folder, fileName) => {
15
14
  const folderPath = `${defaultSettings.srcFolder}/${folder}`;
16
15
  const componentFolderPath = fileName.split('/')[0];
17
16
 
18
- if (!fs.existsSync(folderPath)) {
19
- fs.mkdirSync(folderPath, { recursive: true });
20
- }
21
-
22
17
  if (!fs.existsSync(`${folderPath}/${componentFolderPath}`)) {
23
18
  fs.mkdirSync(`${folderPath}/${componentFolderPath}`, { recursive: true });
24
19
  }
@@ -29,14 +24,14 @@ const streamSharedCompsToDestination = (defaultSettings, folder, fileName) => {
29
24
  } else {
30
25
  const writer = createWriteStream(`${folderPath}/${fileName}`)
31
26
  const options = {
32
- url: `https://${defaultSettings.resourceDomain}/${resourcePath}/${folder}/${fileName}`,
27
+ url: `https://${defaultSettings.nodeEnv}/${resourcePath}/${folder}/${fileName}`,
33
28
  method: 'get',
34
29
  responseType: 'stream'
35
30
  };
36
31
 
37
32
  axios(options).then(resp => {
38
33
  if (resp.status !== 200) {
39
- throw new Error(`${resp.status}: Error while fetching ${url}`);
34
+ throw new Error(`${resp.status}: Error while fetching ${options.url}`);
40
35
  }
41
36
  console.log(`${folderPath}/${fileName} created...`);
42
37
  resp.data.pipe(writer);
@@ -53,15 +48,20 @@ const streamSharedCompsToDestination = (defaultSettings, folder, fileName) => {
53
48
 
54
49
  const getListOfSharedComponents = (defaultSettings, componentFolders) => {
55
50
  return componentFolders.map(folder => {
51
+ const folderPath = `${defaultSettings.srcFolder}/${folder}`;
52
+ if (fs.existsSync(`${folderPath}/`)) {
53
+ return;
54
+ }
55
+
56
56
  return new Promise(resolve => {
57
- axios.get(`https://${defaultSettings.resourceDomain}/${resourcePath}/${folder}/all.json`)
57
+ axios.get(`https://${defaultSettings.nodeEnv}/${resourcePath}/${folder}/all.json`)
58
58
  .then(resp => {
59
59
  if (resp.status !== 200) {
60
60
  throw new Error(`${resp.status}: Error while fetching ${folder}/all.json`);
61
61
  }
62
62
  const listOfComponents = resp.data;
63
63
  const componentPromises = listOfComponents.map(resource => {
64
- return streamSharedCompsToDestination(defaultSettings, folder, `${resource}`);
64
+ return streamSharedCompsToDestination(defaultSettings, folder, `${resource}`);
65
65
  });
66
66
 
67
67
  resolve(Promise.all(componentPromises));
@@ -74,8 +74,7 @@ const getListOfSharedComponents = (defaultSettings, componentFolders) => {
74
74
  });
75
75
  }
76
76
 
77
- export default function(done) {
78
- console.log('running grab-shared-components');
77
+ export default function(config) {
78
+ const componentFolders = config.useAccessibleConfig ? ['accessible-components'] : ['shared-components'];
79
79
  getListOfSharedComponents(defaultSettings, componentFolders);
80
- done();
81
80
  }