mod-build 4.0.80 → 4.0.82-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.82
4
+
5
+ - Added `grab-global-fonts` task to grab Roboto + Montserrat font files from mod-site
6
+ - Added `add-files-to-gitignore` helper task so we can call it whenever needed
7
+
8
+ ## 4.0.81
9
+
10
+ - Updated `grab-shared-scripts.js` to pull growthbook js globally
11
+
3
12
  ## 4.0.80
4
13
 
5
14
  - Add `grab-jsdoc` task to serve process
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mod-build",
3
- "version": "4.0.80",
3
+ "version": "4.0.82-beta.1",
4
4
  "description": "Share components for S3 sites.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,16 +1,16 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
- const entriesToAdd = [
5
- 'jsdoc-types/',
6
- 'modform.jsdoc.js'
7
- ];
8
-
9
- export default async function addJsdocsToGitignore() {
4
+ /**
5
+ * Adds entries to .gitignore file (always appends to bottom)
6
+ * @param {string[]} entries - Array of entries to add to .gitignore
7
+ * @param {string} comment - Optional comment to add before the entries
8
+ * @returns {Promise<void>}
9
+ */
10
+ export default async function addFilesToGitignore(entries, comment) {
10
11
  const gitignorePath = path.join(process.cwd(), '.gitignore');
11
-
12
- let content = '';
13
12
 
13
+ let content = '';
14
14
  try {
15
15
  content = await fs.promises.readFile(gitignorePath, 'utf8');
16
16
  } catch (err) {
@@ -20,10 +20,10 @@ export default async function addJsdocsToGitignore() {
20
20
  }
21
21
 
22
22
  const existingEntries = new Set(content.split('\n').map(line => line.trim()));
23
- const entriesToAppend = entriesToAdd.filter(entry => !existingEntries.has(entry));
23
+ const entriesToAppend = entries.filter(entry => !existingEntries.has(entry));
24
24
 
25
25
  if (entriesToAppend.length === 0) {
26
- console.log('.gitignore already contains jsdoc entries');
26
+ console.log('.gitignore already contains all entries');
27
27
  return;
28
28
  }
29
29
 
@@ -32,9 +32,12 @@ export default async function addJsdocsToGitignore() {
32
32
  ? (content.endsWith('\n') ? '\n' : '\n\n')
33
33
  : '';
34
34
 
35
- contentToAppend += '# JSDoc generated files\n';
35
+ if (comment) {
36
+ contentToAppend += `# ${comment}\n`;
37
+ }
36
38
  contentToAppend += entriesToAppend.join('\n') + '\n';
37
39
 
38
40
  await fs.promises.appendFile(gitignorePath, contentToAppend, 'utf8');
39
41
  console.log(`Added to .gitignore: ${entriesToAppend.join(', ')}`);
40
42
  }
43
+
package/tasks/clean.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
 
3
- const foldersToDelete = ['./src/resources', './src/accessible-components', './src/shared-components', './src/.tmp', './src/temp', './public/resources', './jsdoc-types'];
3
+ const foldersToDelete = ['./src/resources', './src/accessible-components', './src/shared-components', './src/.tmp', './src/temp', './public/resources', './jsdoc-types', './public/fonts/montserrat', './public/fonts/roboto'];
4
4
 
5
5
  const filesToDelete = ['./modform.jsdoc.js'];
6
6
 
@@ -0,0 +1,97 @@
1
+ import { defaultSettings } from '../src/data/config.js';
2
+ import axios from 'axios';
3
+ import { createWriteStream } from 'node:fs';
4
+ import * as stream from 'node:stream';
5
+ import { promisify } from 'node:util';
6
+ import fs from 'node:fs';
7
+ import { responseInterceptor } from '../src/scripts/retry-axios.js';
8
+ import addFilesToGitignore from './add-files-to-gitignore.js';
9
+
10
+ const resourcePath = 'quote/resources/mod-site/fonts';
11
+
12
+ // Global font names
13
+ const fontNames = [
14
+ 'roboto',
15
+ 'montserrat'
16
+ ];
17
+
18
+ // Font variants and extensions to download for each font
19
+ const fontVariants = ['regular', 'bold'];
20
+ const fontExtensions = ['ttf', 'woff2'];
21
+
22
+ // Generate array of all font files needed for download
23
+ const fontFiles = fontNames.flatMap(fontName => {
24
+ return fontVariants.flatMap(variant => {
25
+ return fontExtensions.map(ext => {
26
+ return `${fontName}/${fontName}-${variant}.${ext}`;
27
+ });
28
+ });
29
+ });
30
+
31
+ const axiosInstance = axios.create();
32
+ responseInterceptor(axiosInstance);
33
+
34
+ const streamFontToDestination = (defaultSettings, fontPath) => {
35
+ const finished = promisify(stream.finished);
36
+
37
+ return new Promise(resolve => {
38
+ const filePath = `${defaultSettings.publicFolder}/${defaultSettings.fontsSubfolder}/${fontPath}`;
39
+ const folderPath = filePath.split('/').slice(0, -1).join('/');
40
+
41
+ // Create directory if it doesn't exist
42
+ if (!fs.existsSync(folderPath)) {
43
+ fs.mkdirSync(folderPath, { recursive: true });
44
+ }
45
+
46
+ // if file exists, do not create it again
47
+ if (fs.existsSync(filePath)) {
48
+ resolve();
49
+ } else {
50
+ const writer = createWriteStream(filePath);
51
+ const options = {
52
+ url: `https://${defaultSettings.nodeEnv}/${resourcePath}/${fontPath}`,
53
+ method: 'get',
54
+ responseType: 'stream'
55
+ };
56
+
57
+ axios(options).then(resp => {
58
+ if (resp.status !== 200) {
59
+ throw new Error(`${resp.status}: Error while fetching ${options.url}`);
60
+ }
61
+ console.log(`${filePath} copied...`);
62
+ resp.data.pipe(writer);
63
+ return finished(writer);
64
+ }).then(() => {
65
+ resolve();
66
+ }).catch(error => {
67
+ console.error(error);
68
+ throw new Error(`${error?.response?.statusText} [${error?.status}]: Error while fetching ${options.url}`);
69
+ });
70
+ }
71
+ });
72
+ };
73
+
74
+ const updateGitignore = async () => {
75
+ const fontEntries = fontNames.map(fontName =>
76
+ `${defaultSettings.publicFolder}/${defaultSettings.fontsSubfolder}/${fontName}/`
77
+ );
78
+
79
+ await addFilesToGitignore(fontEntries, 'Global fonts');
80
+ };
81
+
82
+ export default function() {
83
+ const fontsPath = `${defaultSettings.publicFolder}/${defaultSettings.fontsSubfolder}`;
84
+ if (!fs.existsSync(fontsPath)) {
85
+ fs.mkdirSync(fontsPath, { recursive: true });
86
+ }
87
+
88
+ // Download all font files
89
+ const fontPromises = fontFiles.map(fontPath => {
90
+ return streamFontToDestination(defaultSettings, fontPath);
91
+ });
92
+
93
+ return Promise.all(fontPromises).then(async () => {
94
+ // Update .gitignore after fonts are downloaded
95
+ await updateGitignore();
96
+ });
97
+ }
@@ -5,7 +5,7 @@ import * as stream from 'node:stream';
5
5
  import { promisify } from 'node:util';
6
6
  import path from 'node:path';
7
7
  import { responseInterceptor } from '../src/scripts/retry-axios.js';
8
- import addJSDocsToGitignore from './add-jsdocs-to-gitignore.js';
8
+ import addFilesToGitignore from './add-files-to-gitignore.js';
9
9
 
10
10
  const resourcePath = 'quote/resources/mod-form/form';
11
11
  const axiosInstance = axios.create();
@@ -106,6 +106,11 @@ export default async function grabJSDoc() {
106
106
  const files = await getJSDocFiles();
107
107
  const filesPromiseMap = files.map(filePath => streamToDestination(filePath));
108
108
  await Promise.all(filesPromiseMap);
109
- await addJSDocsToGitignore();
109
+
110
+ const gitIgnoreFiles = [
111
+ 'jsdoc-types/',
112
+ 'modform.jsdoc.js'
113
+ ];
114
+ await addFilesToGitignore(gitIgnoreFiles, 'JSDoc generated files');
110
115
  }
111
116
 
@@ -41,15 +41,17 @@ function replaceFootAssetScripts(gulp, defaultSettings) {
41
41
  const resourcePath = '/resources/scripts';
42
42
  return new Promise((resolve) => {
43
43
  gulp.src(`${defaultSettings.srcFolder}/${componentFolderPath}/foot-assets/foot-assets.html`)
44
- .pipe(replace(/"(?:(?!"|js")[\s\S])+(modutils|mod-utils.*?)js"|"(?:(?!"|")[\s\S])+(callrail.*?)js"|"(?:(?!"|")[\s\S])+(footer\/footer-component.*?)js"|"(?:(?!"|")[\s\S])+(mod-form\/form.*?)js"/g, function(match) {
44
+ .pipe(replace(/"(?:(?!"|js")[\s\S])+(modutils|mod-utils.*?)js"|"(?:(?!"|js")[\s\S])+(growthbook.*?)js"|"(?:(?!"|")[\s\S])+(callrail.*?)js"|"(?:(?!"|")[\s\S])+(footer\/footer-component.*?)js"|"(?:(?!"|")[\s\S])+(mod-form\/form.*?)js"/g, function(match) {
45
45
  if (match.includes('mod-form/form/homeowner')) {
46
46
  return `"${resourcePath}/mod-form/form/${fileNames.homeownerFormFileName}"`;
47
47
  } else if (match.includes('mod-form/form/contractor')) {
48
48
  return `"${resourcePath}/mod-form/form/${fileNames.contractorFormFileName}"`;
49
49
  } else if (match.includes('callrail')) {
50
50
  return `"${resourcePath}/callrail/${fileNames.callrailFileName}"`;
51
- } else if (match.includes('modutils') || match.includes('mod-utils')) {
51
+ } else if ((match.includes('modutils') || match.includes('mod-utils')) && !match.includes('growthbook')) {
52
52
  return `"${resourcePath}/mod-utils/${fileNames.modUtilsFileName}"`;
53
+ } else if (match.includes('mod-utils') && match.includes('growthbook')) {
54
+ return `"${resourcePath}/mod-utils/${fileNames.growthBookFileName}"`;
53
55
  } else if (match.includes('footer-component')) {
54
56
  return `"${resourcePath}/footer/${fileNames.footerComponentJsFileName}"`;
55
57
  }
@@ -105,6 +107,15 @@ const TASKS = {
105
107
  },
106
108
  srcReplaceFn: null
107
109
  },
110
+ copyGrowthBook: {
111
+ url: 'mod-utils/growthbook.min.js',
112
+ config: {
113
+ fileName: 'growthBookFileName',
114
+ dest: 'scripts/mod-utils',
115
+ hasMapFile: true
116
+ },
117
+ srcReplaceFn: null
118
+ },
108
119
  copyCallrail: {
109
120
  url: 'shared-resources/scripts/callrail/callrail.min.js',
110
121
  config: {
@@ -250,7 +261,7 @@ function getResource(task, fileNames, resourcePath = 'quote/resources') {
250
261
  });
251
262
  })
252
263
  .then(() => {
253
- if (!config.hasMapFile) {
264
+ if (!config.hasMapFile) {
254
265
  return false;
255
266
  }
256
267
 
package/tasks/serve.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import addEditorConfig from './add-editorconfig.js';
2
+ import grabGlobalFonts from './grab-global-fonts.js';
2
3
  import grabSharedComponents from './grab-shared-components.js';
3
4
  import grabSharedScripts from './grab-shared-scripts.js';
4
5
  import grabCdn from './grab-cdn.js';
@@ -12,6 +13,7 @@ import { createStylelintFile, updateConfig } from '../src/scripts/plugins.js';
12
13
  export async function startModBuild(config) {
13
14
  addEditorConfig();
14
15
  createStylelintFile();
16
+ grabGlobalFonts();
15
17
  await grabB2BData(config);
16
18
  await grabCdn(config);
17
19
  await getDefaultTradeQuestions(config);