Fix ESM detection: try CJS then fall back to data URL import on SyntaxError

This commit is contained in:
2026-04-18 20:43:44 +10:00
parent 0e7edc3aab
commit 9bd1dd325f

View File

@@ -22,22 +22,24 @@
/** /**
* Evaluates plugin source code and returns the plugin object. * Evaluates plugin source code and returns the plugin object.
* Tries CJS eval first; falls back to ESM data-URL import for ES module syntax. * Tries CJS eval first; on SyntaxError falls back to ESM data-URL import.
* @param {string} code * @param {string} code
* @returns {Promise<object>} * @returns {Promise<object>}
*/ */
async function evalPluginCode(code) { async function evalPluginCode(code) {
const isESM = /^\s*(import\s|export\s)/m.test(code); try {
if (!isESM) {
// CommonJS path
const m = { exports: {} }; const m = { exports: {} };
// eslint-disable-next-line no-new-func // eslint-disable-next-line no-new-func
new Function('module', 'exports', code)(m, m.exports); new Function('module', 'exports', code)(m, m.exports);
return m.exports?.default ?? m.exports; const result = m.exports?.default ?? m.exports;
if (result && typeof result === 'object') return result;
// Fall through to ESM if exports came back empty
} catch (err) {
if (!(err instanceof SyntaxError)) throw err;
// SyntaxError means ESM — fall through below
} }
// ESM path — import via data URL so the JS engine handles the module syntax // ESM path — import via data URL so the engine handles module syntax natively
const dataUrl = `data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`; const dataUrl = `data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`;
const mod = await import(dataUrl); const mod = await import(dataUrl);
return mod.default ?? mod; return mod.default ?? mod;