Files
cinny/scripts/patch-folds.mjs
T

64 lines
2.6 KiB
JavaScript
Raw Normal View History

import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { join, dirname } from 'path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const foldsPath = join(__dirname, '../node_modules/folds/dist/index.js');
const foldsPkgPath = join(__dirname, '../node_modules/folds/package.json');
// Context lines around the target, not just the single `children: src(filled)`
// expression, so a coincidental match elsewhere in the bundle (e.g. some other
// `src(filled)` call) can't be mistaken for the Icon component we're patching.
// This is still string matching, not an AST edit, but the extra context makes
// an accidental match far less likely (Gitea #55).
const original = [' ...props,', ' ref,', ' children: src(filled)', ' }'].join(
'\n',
);
const patched = [
' ...props,',
' ref,',
' children: typeof src === "function" ? src(filled) : null',
' }',
].join('\n');
function foldsVersion() {
try {
return JSON.parse(readFileSync(foldsPkgPath, 'utf8')).version ?? 'unknown';
} catch {
return 'unknown';
}
}
try {
const content = readFileSync(foldsPath, 'utf8');
if (content.includes(patched)) {
// Already patched (e.g. re-running postinstall, or a fresh checkout that
// already has a patched node_modules cache) — no-op, exit 0.
console.log('folds patch already applied.');
} else if (content.includes(original)) {
writeFileSync(foldsPath, content.replace(original, patched), 'utf8');
console.log('Applied defensive Icon src guard to folds.');
} else {
// Genuine "patch could not be applied" case: neither the original nor the
// patched form was found, meaning folds changed the Icon implementation.
// Fail loudly so the postinstall hook / CI breaks instead of silently
// shipping an unpatched folds (which crashes at render with "src is not a
// function"). See LOTUS_TODO.md "Dependencies / Build / Hygiene" for
// context on why this is a direct node_modules patch rather than
// patch-package.
console.error('ERROR: folds Icon patch target not found.');
console.error(` folds version installed: ${foldsVersion()}`);
console.error(` Expected to find (surrounding context):\n${original}`);
console.error(
' folds likely changed its Icon implementation. Update the patch target ' +
'in scripts/patch-folds.mjs (see LOTUS_TODO -> "Dependencies / Build / Hygiene" ' +
'-> patch-folds.mjs entry) before building.',
);
process.exit(1);
}
} catch (e) {
console.error('ERROR: Could not patch folds:', e.message);
process.exit(1);
}