mnfst-render 0.5.16 → 0.5.17
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/manifest.render.mjs +38 -6
- package/package.json +1 -1
package/manifest.render.mjs
CHANGED
|
@@ -1474,6 +1474,26 @@ function loadContentForPrerender(manifest, rootDir, locale) {
|
|
|
1474
1474
|
content = parseCsvToKeyValue(join(rootDir, data.slice(1)), loc);
|
|
1475
1475
|
} else if (data && typeof data === 'object' && data.locales && typeof data.locales === 'string') {
|
|
1476
1476
|
content = parseCsvToKeyValue(join(rootDir, data.locales.slice(1)), loc);
|
|
1477
|
+
} else if (data && typeof data === 'object' && !Array.isArray(data)) {
|
|
1478
|
+
// Per-locale files: { "en": "/data/content.en.yaml", "fr": "/data/content.fr.yaml", ... }
|
|
1479
|
+
const filePath = data[loc] || data[Object.keys(data)[0]];
|
|
1480
|
+
if (typeof filePath === 'string') {
|
|
1481
|
+
const fullPath = join(rootDir, filePath.startsWith('/') ? filePath.slice(1) : filePath);
|
|
1482
|
+
if (existsSync(fullPath)) {
|
|
1483
|
+
try {
|
|
1484
|
+
const raw = readFileSync(fullPath, 'utf8');
|
|
1485
|
+
if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {
|
|
1486
|
+
let jsYaml = null;
|
|
1487
|
+
try { jsYaml = require('js-yaml'); } catch { /* skip */ }
|
|
1488
|
+
if (jsYaml) content = jsYaml.load(raw) || {};
|
|
1489
|
+
} else if (filePath.endsWith('.json')) {
|
|
1490
|
+
content = JSON.parse(raw);
|
|
1491
|
+
} else if (filePath.endsWith('.csv')) {
|
|
1492
|
+
content = parseCsvToKeyValue(fullPath, loc);
|
|
1493
|
+
}
|
|
1494
|
+
} catch { /* ignore parse errors */ }
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1477
1497
|
}
|
|
1478
1498
|
if (manifest.description !== undefined && content.description === undefined) {
|
|
1479
1499
|
content.description = manifest.description;
|
|
@@ -1546,15 +1566,27 @@ function resolveHeadXBindings(html, xData) {
|
|
|
1546
1566
|
.replace(/>/g, '>')
|
|
1547
1567
|
.replace(/"/g, '"');
|
|
1548
1568
|
return html.replace(/<head>([\s\S]*?)<\/head>/i, (_, headContent) => {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1569
|
+
// Process each tag in <head> that has a :attr or x-bind:attr binding
|
|
1570
|
+
const out = headContent.replace(/<[^>]+>/g, (tag) => {
|
|
1571
|
+
// Find all :attr="$x...." or x-bind:attr="$x...." bindings in this tag
|
|
1572
|
+
const bindingRe = /\s(?::|x-bind:)(\w+)=["'](\$x\.[^"']+)["']/g;
|
|
1573
|
+
let m;
|
|
1574
|
+
let newTag = tag;
|
|
1575
|
+
while ((m = bindingRe.exec(tag)) !== null) {
|
|
1576
|
+
const attr = m[1];
|
|
1577
|
+
const expr = m[2];
|
|
1552
1578
|
const path = expr.replace(/^\$x\./, '').trim();
|
|
1553
1579
|
const value = getXPath(xData, path);
|
|
1554
|
-
if (value === undefined)
|
|
1555
|
-
|
|
1580
|
+
if (value === undefined) continue;
|
|
1581
|
+
// Remove the binding
|
|
1582
|
+
newTag = newTag.replace(m[0], '');
|
|
1583
|
+
// Remove existing static fallback for this attr
|
|
1584
|
+
newTag = newTag.replace(new RegExp(`\\s${attr}=["'][^"']*["']`), '');
|
|
1585
|
+
// Insert the resolved attr before the closing >
|
|
1586
|
+
newTag = newTag.replace(/>$/, ` ${attr}="${esc(value)}">`);
|
|
1556
1587
|
}
|
|
1557
|
-
|
|
1588
|
+
return newTag;
|
|
1589
|
+
});
|
|
1558
1590
|
return `<head>${out}</head>`;
|
|
1559
1591
|
});
|
|
1560
1592
|
}
|