mnfst-render 0.4.7 → 0.4.9
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/bin/mnfst-render.js +0 -0
- package/manifest.render.mjs +31 -21
- package/package.json +1 -1
package/bin/mnfst-render.js
CHANGED
|
File without changes
|
package/manifest.render.mjs
CHANGED
|
@@ -229,23 +229,18 @@ function resolveConfig() {
|
|
|
229
229
|
locales: pre.locales,
|
|
230
230
|
redirects: Array.isArray(pre.redirects) ? pre.redirects : [],
|
|
231
231
|
wait: cli.wait ?? pre.wait ?? null,
|
|
232
|
-
waitAfterIdle:
|
|
232
|
+
waitAfterIdle: 0,
|
|
233
233
|
concurrency: Math.max(1, cli.concurrency ?? pre.concurrency ?? Math.max(4, cpus().length - 1)),
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
localeSubstitution: pre.localeSubstitution !== false,
|
|
237
|
-
/** Locales to always render with Puppeteer even when localeSubstitution is enabled (e.g. RTL). */
|
|
238
|
-
localeSubstitutionExclude: Array.isArray(pre.localeSubstitutionExclude)
|
|
239
|
-
? pre.localeSubstitutionExclude.map(String)
|
|
240
|
-
: [],
|
|
234
|
+
localeSubstitution: true,
|
|
235
|
+
localeSubstitutionExclude: [],
|
|
241
236
|
/** Explicit locale-neutral paths to render in addition to those discovered automatically.
|
|
242
237
|
* Each entry is expanded to all locale variants (e.g. "legal/privacy" → "cs/legal/privacy", ...) */
|
|
243
238
|
paths: Array.isArray(pre.paths)
|
|
244
239
|
? pre.paths.map((p) => String(p).replace(/^\/+|\/+$/g, '')).filter(Boolean)
|
|
245
240
|
: [],
|
|
246
241
|
dryRun: !!cli.dryRun,
|
|
247
|
-
debugPrerender: !!
|
|
248
|
-
pipelineTimeout:
|
|
242
|
+
debugPrerender: !!cli.debugPrerender,
|
|
243
|
+
pipelineTimeout: 25000,
|
|
249
244
|
};
|
|
250
245
|
}
|
|
251
246
|
|
|
@@ -694,13 +689,11 @@ function promptContinueWithRuntimeTailwind(rootDir) {
|
|
|
694
689
|
|
|
695
690
|
/**
|
|
696
691
|
* Build a static Tailwind stylesheet via @tailwindcss/cli (v4+), scanning project sources.
|
|
697
|
-
* Only runs when the project
|
|
692
|
+
* Only runs when the project uses data-tailwind on the manifest script tag (auto-detected).
|
|
693
|
+
* Set manifest.prerender.tailwindInput to a custom CSS entry file if needed.
|
|
698
694
|
*/
|
|
699
695
|
function runTailwindCliForPrerender(rootDir, outputDir, pre) {
|
|
700
|
-
|
|
701
|
-
if (explicit === false) return false;
|
|
702
|
-
const usesTailwind = explicit === true || indexHtmlUsesTailwind(rootDir);
|
|
703
|
-
if (!usesTailwind) return false;
|
|
696
|
+
if (!indexHtmlUsesTailwind(rootDir)) return false;
|
|
704
697
|
|
|
705
698
|
const outCss = join(outputDir, 'prerender.tailwind.css');
|
|
706
699
|
try {
|
|
@@ -708,7 +701,7 @@ function runTailwindCliForPrerender(rootDir, outputDir, pre) {
|
|
|
708
701
|
} catch {
|
|
709
702
|
const proceed = promptContinueWithRuntimeTailwind(rootDir);
|
|
710
703
|
if (!proceed) {
|
|
711
|
-
throw new Error('prerender aborted: install tailwindcss/@tailwindcss/cli or
|
|
704
|
+
throw new Error('prerender aborted: install tailwindcss/@tailwindcss/cli or remove data-tailwind from your manifest script tag.');
|
|
712
705
|
}
|
|
713
706
|
process.stdout.write('prerender: continuing with runtime data-tailwind behavior.\n');
|
|
714
707
|
return false;
|
|
@@ -726,15 +719,12 @@ function runTailwindCliForPrerender(rootDir, outputDir, pre) {
|
|
|
726
719
|
}
|
|
727
720
|
|
|
728
721
|
const outputBasename = basename(outputDir);
|
|
729
|
-
const
|
|
722
|
+
const contentGlobs = [
|
|
730
723
|
'**/*.html',
|
|
731
724
|
'!**/node_modules/**',
|
|
732
725
|
'!**/dist/**',
|
|
733
726
|
`!**/${outputBasename}/**`,
|
|
734
727
|
];
|
|
735
|
-
const contentGlobs = Array.isArray(pre?.tailwindContent) && pre.tailwindContent.length > 0
|
|
736
|
-
? pre.tailwindContent
|
|
737
|
-
: defaultContent;
|
|
738
728
|
|
|
739
729
|
const args = [
|
|
740
730
|
'--yes',
|
|
@@ -762,7 +752,7 @@ function runTailwindCliForPrerender(rootDir, outputDir, pre) {
|
|
|
762
752
|
}
|
|
763
753
|
}
|
|
764
754
|
if (r.status !== 0) {
|
|
765
|
-
console.error('prerender: Tailwind CLI failed; install with `npm i -D tailwindcss @tailwindcss/cli` or
|
|
755
|
+
console.error('prerender: Tailwind CLI failed; install with `npm i -D tailwindcss @tailwindcss/cli` or check tailwindInput in manifest.prerender.');
|
|
766
756
|
if (r.stderr) console.error(r.stderr);
|
|
767
757
|
if (r.stdout) console.error(r.stdout);
|
|
768
758
|
return false;
|
|
@@ -1144,6 +1134,9 @@ function loadAllLocaleContentData(manifest, rootDir, locales) {
|
|
|
1144
1134
|
target[key] = (target[key] && typeof target[key] === 'object') ? target[key] : {};
|
|
1145
1135
|
deepMerge(target[key], source[key]);
|
|
1146
1136
|
} else {
|
|
1137
|
+
// Don't overwrite an existing nested object with a primitive — that creates
|
|
1138
|
+
// type asymmetry across locales and causes '[object Object]' in substitution pairs
|
|
1139
|
+
if (target[key] && typeof target[key] === 'object') continue;
|
|
1147
1140
|
target[key] = source[key];
|
|
1148
1141
|
}
|
|
1149
1142
|
}
|
|
@@ -1152,12 +1145,25 @@ function loadAllLocaleContentData(manifest, rootDir, locales) {
|
|
|
1152
1145
|
const result = new Map();
|
|
1153
1146
|
for (const locale of locales) result.set(locale, {});
|
|
1154
1147
|
|
|
1148
|
+
// Read just the header row of a CSV to check which locale columns it contains.
|
|
1149
|
+
function csvLocaleColumns(csvPath) {
|
|
1150
|
+
if (!existsSync(csvPath)) return new Set();
|
|
1151
|
+
try {
|
|
1152
|
+
const firstLine = readFileSync(csvPath, 'utf8').split(/\r?\n/)[0] || '';
|
|
1153
|
+
return new Set(splitCsvLine(firstLine).slice(1)); // skip key column
|
|
1154
|
+
} catch { return new Set(); }
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1155
1157
|
for (const [, value] of Object.entries(data)) {
|
|
1156
1158
|
if (typeof value === 'string') {
|
|
1157
1159
|
// Single CSV with locale columns (all locales in one file)
|
|
1158
1160
|
if (value.endsWith('.csv')) {
|
|
1159
1161
|
const csvPath = join(rootDir, value.startsWith('/') ? value.slice(1) : value);
|
|
1162
|
+
const cols = csvLocaleColumns(csvPath);
|
|
1160
1163
|
for (const locale of locales) {
|
|
1164
|
+
// Only include locales the CSV actually declares; falling back to the English
|
|
1165
|
+
// column for a missing locale silently poisons substitution pairs with English values.
|
|
1166
|
+
if (!cols.has(locale)) continue;
|
|
1161
1167
|
deepMerge(result.get(locale), parseCsvToKeyValue(csvPath, locale));
|
|
1162
1168
|
}
|
|
1163
1169
|
}
|
|
@@ -1168,7 +1174,9 @@ function loadAllLocaleContentData(manifest, rootDir, locales) {
|
|
|
1168
1174
|
for (const ref of refs) {
|
|
1169
1175
|
if (typeof ref !== 'string' || !ref.endsWith('.csv')) continue;
|
|
1170
1176
|
const csvPath = join(rootDir, ref.startsWith('/') ? ref.slice(1) : ref);
|
|
1177
|
+
const cols = csvLocaleColumns(csvPath);
|
|
1171
1178
|
for (const locale of locales) {
|
|
1179
|
+
if (!cols.has(locale)) continue;
|
|
1172
1180
|
deepMerge(result.get(locale), parseCsvToKeyValue(csvPath, locale));
|
|
1173
1181
|
}
|
|
1174
1182
|
}
|
|
@@ -1215,6 +1223,8 @@ function buildSubstitutionPairs(defaultLocaleData, targetLocaleData) {
|
|
|
1215
1223
|
// Recurse into nested objects (produced by setNestedKey for dotted CSV keys)
|
|
1216
1224
|
collectPairs(defaultVal, targetVal && typeof targetVal === 'object' ? targetVal : {});
|
|
1217
1225
|
} else {
|
|
1226
|
+
// Skip if target is a non-primitive — String(obj) === '[object Object]' is never useful
|
|
1227
|
+
if (targetVal !== null && typeof targetVal === 'object') continue;
|
|
1218
1228
|
const from = String(defaultVal ?? '').trim();
|
|
1219
1229
|
const to = String(targetVal ?? '').trim();
|
|
1220
1230
|
if (!from || from === to) continue;
|