41 lines
1.7 KiB
JavaScript
41 lines
1.7 KiB
JavaScript
// Phase 2 dart-sass recompile (ARCHITECTURE.md 7.5). Lazy and defensive: the
|
|
// `sass` dependency and the vendored Bootstrap SCSS under ../scss are Phase-2
|
|
// only, so a missing dep or compile error degrades to the Phase-1 overlay
|
|
// rather than white-screening. Only ever reached for engine:"sass" themes.
|
|
|
|
const path = require("path");
|
|
const { sanitizeValue } = require("./sanitize"); // shared guard (folded fix)
|
|
|
|
|
|
function compileSass(tokens, opts = {}) {
|
|
const warnings = [];
|
|
try {
|
|
const sass = require("sass"); // lazy; Phase-2 dep
|
|
const flat = require("./compile").flattenTokens(tokens);
|
|
const varBlock = Object.entries(flat)
|
|
.filter(([k]) => /^[-a-zA-Z0-9_]{1,64}$/.test(k))
|
|
.map(([k, v]) => {
|
|
const sv = sanitizeValue(v, warnings);
|
|
return sv == null ? "" : `$${k}: ${sv};`;
|
|
})
|
|
.filter(Boolean)
|
|
.join("\n");
|
|
const scssDir = path.join(__dirname, "..", "scss");
|
|
// relative module id resolved via loadPaths; no absolute @import string.
|
|
const entry = `@use "bootstrap/bootstrap" with (\n${varBlock}\n);\n`;
|
|
const result = sass.compileString(entry, {
|
|
loadPaths: [scssDir],
|
|
style: "compressed",
|
|
logger: { warn: (m) => warnings.push(m), debug: () => {} },
|
|
});
|
|
return { css: result.css, warnings };
|
|
} catch (e) {
|
|
warnings.push("sass compile unavailable/failed: " + e.message);
|
|
// fall back to the overlay; never white-screen.
|
|
const overlay = require("./compile").emitOverlayCss(tokens);
|
|
return { css: overlay.css, warnings: warnings.concat(overlay.warnings || []) };
|
|
}
|
|
}
|
|
|
|
|
|
module.exports = { compileSass };
|