mod-build 4.0.82 → 4.0.83-beta.2
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 +4 -0
- package/package.json +1 -1
- package/tasks/add-files-to-gitignore.js +28 -11
- package/tasks/clean.js +9 -1
- package/tasks/grab-global-fonts.js +125 -48
- package/tasks/serve.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.83
|
|
4
|
+
|
|
5
|
+
- Updated `grab-global-fonts` task to grab fonts from `gwfh.mranftl.com/api/fonts` -- will default to `Roboto` unless defined in `siteconfig.js` = `fontsToDownload: ['font-name']`
|
|
6
|
+
|
|
3
7
|
## 4.0.82
|
|
4
8
|
|
|
5
9
|
- Added `grab-global-fonts` task to grab Roboto + Montserrat font files from mod-site
|
package/package.json
CHANGED
|
@@ -2,7 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Adds entries to .gitignore file
|
|
5
|
+
* Adds entries to .gitignore file
|
|
6
|
+
* If a section with the same comment exists, adds entries below it; otherwise, appends to bottom
|
|
6
7
|
* @param {string[]} entries - Array of entries to add to .gitignore
|
|
7
8
|
* @param {string} comment - Optional comment to add before the entries
|
|
8
9
|
* @returns {Promise<void>}
|
|
@@ -27,17 +28,33 @@ export default async function addFilesToGitignore(entries, comment) {
|
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
//
|
|
31
|
-
let contentToAppend = content.trim()
|
|
32
|
-
? (content.endsWith('\n') ? '\n' : '\n\n')
|
|
33
|
-
: '';
|
|
34
|
-
|
|
31
|
+
// If comment exists, find the section and insert below it
|
|
35
32
|
if (comment) {
|
|
36
|
-
|
|
33
|
+
const commentLine = `# ${comment}`;
|
|
34
|
+
const lines = content.split('\n');
|
|
35
|
+
const sectionIndex = lines.findIndex(line => line.trim() === commentLine);
|
|
36
|
+
|
|
37
|
+
if (sectionIndex !== -1) {
|
|
38
|
+
let insertIndex = sectionIndex + 1;
|
|
39
|
+
let lastNonBlankIndex = sectionIndex;
|
|
40
|
+
|
|
41
|
+
while (insertIndex < lines.length && !lines[insertIndex].trim().startsWith('#')) {
|
|
42
|
+
if (lines[insertIndex].trim() !== '') {
|
|
43
|
+
lastNonBlankIndex = insertIndex;
|
|
44
|
+
}
|
|
45
|
+
insertIndex++;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
lines.splice(lastNonBlankIndex + 1, 0, ...entriesToAppend);
|
|
49
|
+
await fs.promises.writeFile(gitignorePath, lines.join('\n') + '\n', 'utf8');
|
|
50
|
+
console.log(`Added to .gitignore ${comment} section: ${entriesToAppend.join(', ')}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
37
53
|
}
|
|
38
|
-
contentToAppend += entriesToAppend.join('\n') + '\n';
|
|
39
54
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
55
|
+
const separator = content.trim() ? (content.endsWith('\n') ? '\n' : '\n\n') : '';
|
|
56
|
+
const newContent = comment ? `${separator}# ${comment}\n${entriesToAppend.join('\n')}\n` : `${separator}${entriesToAppend.join('\n')}\n`;
|
|
43
57
|
|
|
58
|
+
await fs.promises.appendFile(gitignorePath, newContent, 'utf8');
|
|
59
|
+
console.log(`Added to .gitignore: ${entriesToAppend.join(', ')}`);
|
|
60
|
+
}
|
package/tasks/clean.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const baseFoldersToDelete = ['./src/resources', './src/accessible-components', './src/shared-components', './src/.tmp', './src/temp', './public/resources', './jsdoc-types'];
|
|
4
4
|
|
|
5
5
|
const filesToDelete = ['./modform.jsdoc.js'];
|
|
6
6
|
|
|
7
|
+
// We will want to delete all downloaded fonts (which will be all folders but ./public/fonts/branded/*)
|
|
8
|
+
const fontBaseFolder = './public/fonts';
|
|
9
|
+
const fontFoldersToDelete = fs.readdirSync(fontBaseFolder, { withFileTypes: true })
|
|
10
|
+
.filter(dirent => dirent.isDirectory() && dirent.name !== 'branded')
|
|
11
|
+
.map(dirent => path.join(fontBaseFolder, dirent.name));
|
|
12
|
+
|
|
13
|
+
const foldersToDelete = [...baseFoldersToDelete, ...fontFoldersToDelete];
|
|
14
|
+
|
|
7
15
|
foldersToDelete.forEach(async (folder) => {
|
|
8
16
|
try {
|
|
9
17
|
await fs.promises.rm(folder, { recursive: true });
|
|
@@ -4,74 +4,147 @@ import { createWriteStream } from 'node:fs';
|
|
|
4
4
|
import * as stream from 'node:stream';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
7
8
|
import { responseInterceptor } from '../src/scripts/retry-axios.js';
|
|
8
9
|
import addFilesToGitignore from './add-files-to-gitignore.js';
|
|
9
10
|
|
|
10
|
-
const resourcePath = 'quote/resources/mod-site/fonts';
|
|
11
|
-
|
|
12
|
-
// Global font names
|
|
13
|
-
const fontNames = [
|
|
14
|
-
'roboto',
|
|
15
|
-
'montserrat'
|
|
16
|
-
];
|
|
17
|
-
|
|
18
11
|
// Font variants and extensions to download for each font
|
|
19
12
|
const fontVariants = ['regular', 'bold'];
|
|
20
13
|
const fontExtensions = ['ttf', 'woff2'];
|
|
21
14
|
|
|
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
15
|
const axiosInstance = axios.create();
|
|
32
16
|
responseInterceptor(axiosInstance);
|
|
33
17
|
|
|
34
|
-
const
|
|
18
|
+
const directoryHasItems = (dirPath) => {
|
|
19
|
+
if (!fs.existsSync(dirPath)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const items = fs.readdirSync(dirPath);
|
|
23
|
+
return items.length > 0;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const getFontDownloadUrls = async (fontName) => {
|
|
27
|
+
try {
|
|
28
|
+
const url = `https://gwfh.mranftl.com/api/fonts/${fontName}?subsets=latin`;
|
|
29
|
+
const response = await axiosInstance.get(url);
|
|
30
|
+
const fontData = response.data;
|
|
31
|
+
|
|
32
|
+
if (!fontData || !fontData.variants) {
|
|
33
|
+
throw new Error('Invalid font data received');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const downloadUrls = {};
|
|
37
|
+
|
|
38
|
+
const targetWeights = ['400', '700'];
|
|
39
|
+
|
|
40
|
+
fontData.variants.forEach(variant => {
|
|
41
|
+
if (variant.fontStyle === 'normal' && targetWeights.includes(variant.fontWeight)) {
|
|
42
|
+
const variantName = variant.fontWeight === '400' ? 'regular' : 'bold';
|
|
43
|
+
|
|
44
|
+
if (!downloadUrls[variantName]) {
|
|
45
|
+
downloadUrls[variantName] = {};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (variant.ttf) {
|
|
49
|
+
downloadUrls[variantName].ttf = variant.ttf;
|
|
50
|
+
}
|
|
51
|
+
if (variant.woff2) {
|
|
52
|
+
downloadUrls[variantName].woff2 = variant.woff2;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return downloadUrls;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error(`Error fetching font data for ${fontName}:`, error.message);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const downloadFontFile = async (defaultSettings, fontName, variant, extension, downloadUrl) => {
|
|
35
65
|
const finished = promisify(stream.finished);
|
|
36
66
|
|
|
37
|
-
return new Promise(resolve => {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const fileName = `${fontName}-${variant}.${extension}`;
|
|
69
|
+
const filePath = path.join(
|
|
70
|
+
defaultSettings.publicFolder,
|
|
71
|
+
defaultSettings.fontsSubfolder,
|
|
72
|
+
fontName,
|
|
73
|
+
fileName
|
|
74
|
+
);
|
|
75
|
+
const folderPath = path.dirname(filePath);
|
|
40
76
|
|
|
41
|
-
// Create directory if it doesn't exist
|
|
42
77
|
if (!fs.existsSync(folderPath)) {
|
|
43
78
|
fs.mkdirSync(folderPath, { recursive: true });
|
|
44
79
|
}
|
|
45
80
|
|
|
46
|
-
// if file exists, do not create it again
|
|
47
81
|
if (fs.existsSync(filePath)) {
|
|
82
|
+
console.log(`${filePath} already exists, skipping...`);
|
|
48
83
|
resolve();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const writer = createWriteStream(filePath);
|
|
88
|
+
|
|
89
|
+
axiosInstance({
|
|
90
|
+
url: downloadUrl,
|
|
91
|
+
method: 'get',
|
|
92
|
+
responseType: 'stream'
|
|
93
|
+
})
|
|
94
|
+
.then(resp => {
|
|
58
95
|
if (resp.status !== 200) {
|
|
59
|
-
throw new Error(`${resp.status}: Error while fetching ${
|
|
96
|
+
throw new Error(`${resp.status}: Error while fetching ${downloadUrl}`);
|
|
60
97
|
}
|
|
61
|
-
console.log(
|
|
98
|
+
console.log(`Downloading ${filePath}...`);
|
|
62
99
|
resp.data.pipe(writer);
|
|
63
100
|
return finished(writer);
|
|
64
|
-
})
|
|
101
|
+
})
|
|
102
|
+
.then(() => {
|
|
103
|
+
console.log(`${filePath} downloaded successfully`);
|
|
65
104
|
resolve();
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
})
|
|
106
|
+
.catch(error => {
|
|
107
|
+
console.error(`Error downloading ${filePath} from ${downloadUrl}:`, error.message);
|
|
108
|
+
reject(new Error(`Failed to download ${filePath}: ${error.message}`));
|
|
69
109
|
});
|
|
70
|
-
}
|
|
71
110
|
});
|
|
72
111
|
};
|
|
73
112
|
|
|
74
|
-
const
|
|
113
|
+
const downloadFont = async (defaultSettings, fontName) => {
|
|
114
|
+
const fontDir = path.join(
|
|
115
|
+
defaultSettings.publicFolder,
|
|
116
|
+
defaultSettings.fontsSubfolder,
|
|
117
|
+
fontName
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
if (directoryHasItems(fontDir)) {
|
|
121
|
+
console.log(`Font directory ${fontDir} already has items, skipping ${fontName}...`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.log(`Downloading font: ${fontName}`);
|
|
126
|
+
|
|
127
|
+
const downloadUrls = await getFontDownloadUrls(fontName);
|
|
128
|
+
|
|
129
|
+
if (!downloadUrls || Object.keys(downloadUrls).length === 0) {
|
|
130
|
+
throw new Error(`Could not find download URLs for ${fontName}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const downloadPromises = fontVariants.flatMap(variant => {
|
|
134
|
+
return fontExtensions.map(ext => {
|
|
135
|
+
const url = downloadUrls[variant]?.[ext];
|
|
136
|
+
if (!url) {
|
|
137
|
+
console.warn(`Warning: No ${ext} URL found for ${fontName} ${variant}, skipping...`);
|
|
138
|
+
return Promise.resolve();
|
|
139
|
+
}
|
|
140
|
+
return downloadFontFile(defaultSettings, fontName, variant, ext, url);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
await Promise.all(downloadPromises);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const updateGitignore = async (defaultSettings, fontNames) => {
|
|
75
148
|
const fontEntries = fontNames.map(fontName =>
|
|
76
149
|
`${defaultSettings.publicFolder}/${defaultSettings.fontsSubfolder}/${fontName}/`
|
|
77
150
|
);
|
|
@@ -79,19 +152,23 @@ const updateGitignore = async () => {
|
|
|
79
152
|
await addFilesToGitignore(fontEntries, 'Global fonts');
|
|
80
153
|
};
|
|
81
154
|
|
|
82
|
-
|
|
83
|
-
|
|
155
|
+
// If a site has a branded font that is outside of this API - we should add it to /public/fonts/branded/{fontName}/*
|
|
156
|
+
export default function(config) {
|
|
157
|
+
// Download fonts from config.fontsToDownload or will default to ['roboto']
|
|
158
|
+
const fontNames = config?.fontsToDownload && Array.isArray(config.fontsToDownload) && config.fontsToDownload.length > 0
|
|
159
|
+
? config.fontsToDownload
|
|
160
|
+
: ['roboto'];
|
|
161
|
+
|
|
162
|
+
const fontsPath = path.join(defaultSettings.publicFolder, defaultSettings.fontsSubfolder);
|
|
84
163
|
if (!fs.existsSync(fontsPath)) {
|
|
85
164
|
fs.mkdirSync(fontsPath, { recursive: true });
|
|
86
165
|
}
|
|
87
166
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return streamFontToDestination(defaultSettings, fontPath);
|
|
167
|
+
const fontPromises = fontNames.map(fontName => {
|
|
168
|
+
return downloadFont(defaultSettings, fontName);
|
|
91
169
|
});
|
|
92
170
|
|
|
93
171
|
return Promise.all(fontPromises).then(async () => {
|
|
94
|
-
|
|
95
|
-
await updateGitignore();
|
|
172
|
+
await updateGitignore(defaultSettings, fontNames);
|
|
96
173
|
});
|
|
97
|
-
}
|
|
174
|
+
}
|
package/tasks/serve.js
CHANGED
|
@@ -13,7 +13,7 @@ import { createStylelintFile, updateConfig } from '../src/scripts/plugins.js';
|
|
|
13
13
|
export async function startModBuild(config) {
|
|
14
14
|
addEditorConfig();
|
|
15
15
|
createStylelintFile();
|
|
16
|
-
grabGlobalFonts();
|
|
16
|
+
grabGlobalFonts(config);
|
|
17
17
|
await grabB2BData(config);
|
|
18
18
|
await grabCdn(config);
|
|
19
19
|
await getDefaultTradeQuestions(config);
|