2026-05-21 19:26:52 -04:00
|
|
|
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');
|
2026-09-13 00:56:22 -04:00
|
|
|
const foldsPkgPath = join(__dirname, '../node_modules/folds/package.json');
|
2026-05-21 19:26:52 -04:00
|
|
|
|
2026-09-13 00:56:22 -04:00
|
|
|
// 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');
|
2026-05-21 20:49:33 -04:00
|
|
|
|
2026-09-13 00:56:22 -04:00
|
|
|
function foldsVersion() {
|
|
|
|
|
try {
|
|
|
|
|
return JSON.parse(readFileSync(foldsPkgPath, 'utf8')).version ?? 'unknown';
|
|
|
|
|
} catch {
|
|
|
|
|
return 'unknown';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const content = readFileSync(foldsPath, 'utf8');
|
2026-05-21 20:49:33 -04:00
|
|
|
|
2026-05-21 19:26:52 -04:00
|
|
|
if (content.includes(patched)) {
|
2026-09-13 00:56:22 -04:00
|
|
|
// Already patched (e.g. re-running postinstall, or a fresh checkout that
|
|
|
|
|
// already has a patched node_modules cache) — no-op, exit 0.
|
2026-05-21 19:26:52 -04:00
|
|
|
console.log('folds patch already applied.');
|
|
|
|
|
} else if (content.includes(original)) {
|
2026-09-13 00:56:22 -04:00
|
|
|
writeFileSync(foldsPath, content.replace(original, patched), 'utf8');
|
2026-05-21 19:26:52 -04:00
|
|
|
console.log('Applied defensive Icon src guard to folds.');
|
|
|
|
|
} else {
|
2026-09-13 00:56:22 -04:00
|
|
|
// 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
|
2026-09-17 23:26:21 -04:00
|
|
|
// function"). See cinny #210 (build hygiene notes) for
|
2026-09-13 00:56:22 -04:00
|
|
|
// 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}`);
|
2026-06-28 10:55:19 -04:00
|
|
|
console.error(
|
2026-09-13 00:56:22 -04:00
|
|
|
' folds likely changed its Icon implementation. Update the patch target ' +
|
2026-09-17 23:26:21 -04:00
|
|
|
'in scripts/patch-folds.mjs (see cinny #210 ' +
|
2026-09-13 00:56:22 -04:00
|
|
|
'-> patch-folds.mjs entry) before building.',
|
2026-06-28 10:55:19 -04:00
|
|
|
);
|
|
|
|
|
process.exit(1);
|
2026-05-21 19:26:52 -04:00
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2026-06-28 10:55:19 -04:00
|
|
|
console.error('ERROR: Could not patch folds:', e.message);
|
|
|
|
|
process.exit(1);
|
2026-05-21 19:26:52 -04:00
|
|
|
}
|