Fix ESM detection: try CJS then fall back to data URL import on SyntaxError
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user