import babel from "@babel/core";
import esbuild from "esbuild";
import * as colors from "kleur/colors";
import * as eslexer from "es-module-lexer";
import path from "path";
import {error} from "../core/logger.js";
import {parseNpmName} from "../core/util.js";
const JSX_RENDERERS = new Map();
const JSX_EXTENSIONS = new Set([".jsx", ".tsx"]);
const IMPORT_STATEMENTS = {
  react: "import React from 'react'",
  preact: "import { h } from 'preact'",
  "solid-js": "import 'solid-js/web'"
};
const PREVENT_UNUSED_IMPORTS = ";;(React,Fragment,h);";
function jsx({config, logging}) {
  return {
    name: "@astrojs/vite-plugin-jsx",
    enforce: "pre",
    async transform(code, id, ssr) {
      if (!JSX_EXTENSIONS.has(path.extname(id))) {
        return null;
      }
      if (JSX_RENDERERS.size === 0) {
        const jsxRenderers = await loadJSXRenderers(config.renderers);
        if (jsxRenderers.size === 0) {
          throw new Error(`${colors.yellow(id)}
Unable to resolve a renderer that handles JSX transforms! Please include a \`renderer\` plugin which supports JSX in your \`astro.config.mjs\` file.`);
        }
        for (const [importSource2, renderer] of jsxRenderers) {
          JSX_RENDERERS.set(importSource2, renderer);
        }
      }
      if (JSX_RENDERERS.size === 1) {
        return transformJSX({code, id, renderer: [...JSX_RENDERERS.values()][0], ssr: ssr || false});
      }
      const {code: codeToScan} = await esbuild.transform(code + PREVENT_UNUSED_IMPORTS, {
        loader: getLoader(path.extname(id)),
        jsx: "transform",
        jsxFactory: "h",
        jsxFragment: "Fragment"
      });
      let imports = [];
      if (/import/.test(codeToScan)) {
        let [i] = eslexer.parse(codeToScan);
        imports = i;
      }
      let importSource;
      if (imports.length > 0) {
        for (let {n: spec} of imports) {
          const pkg = spec && parseNpmName(spec);
          if (!pkg)
            continue;
          if (JSX_RENDERERS.has(pkg.name)) {
            importSource = pkg.name;
            break;
          }
        }
      }
      if (!importSource) {
        const multiline = code.match(/\/\*\*[\S\s]*\*\//gm) || [];
        for (const comment of multiline) {
          const [_, lib] = comment.match(/@jsxImportSource\s*(\S+)/) || [];
          if (lib) {
            importSource = lib;
            break;
          }
        }
      }
      if (importSource) {
        const jsxRenderer = JSX_RENDERERS.get(importSource);
        if (!jsxRenderer) {
          error(logging, "renderer", `${colors.yellow(id)} No renderer installed for ${importSource}. Try adding \`@astrojs/renderer-${importSource}\` to your dependencies.`);
          return null;
        }
        return transformJSX({code, id, renderer: JSX_RENDERERS.get(importSource), ssr: ssr || false});
      }
      const defaultRenderer = [...JSX_RENDERERS.keys()][0];
      error(logging, "renderer", `${colors.yellow(id)}
Unable to resolve a renderer that handles this file! With more than one renderer enabled, you should include an import or use a pragma comment.
Add ${colors.cyan(IMPORT_STATEMENTS[defaultRenderer] || `import '${defaultRenderer}';`)} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file.
`);
      return null;
    }
  };
}
function getLoader(fileExt) {
  return fileExt.substr(1);
}
async function loadJSXRenderers(rendererNames) {
  const renderers = new Map();
  await Promise.all(rendererNames.map((name) => import(name).then(({default: renderer}) => {
    if (!renderer.jsxImportSource)
      return;
    renderers.set(renderer.jsxImportSource, renderer);
  })));
  return renderers;
}
async function transformJSX({code, id, ssr, renderer}) {
  const {jsxTransformOptions} = renderer;
  const options = await jsxTransformOptions({isSSR: ssr || false});
  const result = await new Promise((resolve, reject) => {
    const plugins = [...options.plugins || []];
    babel.transform(code, {
      presets: options.presets,
      plugins,
      cwd: process.cwd(),
      filename: id,
      ast: false,
      compact: false,
      sourceMaps: true,
      configFile: false,
      babelrc: false
    }, (err, res) => {
      if (err) {
        reject(err);
      } else {
        return resolve(res);
      }
    });
  });
  if (!result)
    return null;
  return {
    code: result.code || "",
    map: result.map
  };
}
export {
  jsx as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3ZpdGUtcGx1Z2luLWpzeC9pbmRleC50cyJdLAogICJtYXBwaW5ncyI6ICJBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTSxnQkFBZ0IsSUFBSTtBQUMxQixNQUFNLGlCQUFpQixJQUFJLElBQUksQ0FBQyxRQUFRO0FBQ3hDLE1BQU0sb0JBQTRDO0FBQUEsRUFDaEQsT0FBTztBQUFBLEVBQ1AsUUFBUTtBQUFBLEVBQ1IsWUFBWTtBQUFBO0FBSWQsTUFBTSx5QkFBeUI7QUFRaEIsYUFBYSxDQUFFLFFBQVEsVUFBMEM7QUFDOUUsU0FBTztBQUFBLElBQ0wsTUFBTTtBQUFBLElBQ04sU0FBUztBQUFBLFVBQ0gsVUFBVSxNQUFNLElBQUksS0FBSztBQUM3QixVQUFJLENBQUMsZUFBZSxJQUFJLEtBQUssUUFBUSxNQUFNO0FBQ3pDLGVBQU87QUFBQTtBQUlULFVBQUksY0FBYyxTQUFTLEdBQUc7QUFDNUIsY0FBTSxlQUFlLE1BQU0saUJBQWlCLE9BQU87QUFDbkQsWUFBSSxhQUFhLFNBQVMsR0FBRztBQUUzQixnQkFBTSxJQUFJLE1BQ1IsR0FBRyxPQUFPLE9BQ1I7QUFBQTtBQUFBO0FBSU4sbUJBQVcsQ0FBQyxlQUFjLGFBQWEsY0FBYztBQUNuRCx3QkFBYyxJQUFJLGVBQWM7QUFBQTtBQUFBO0FBS3BDLFVBQUksY0FBYyxTQUFTLEdBQUc7QUFDNUIsZUFBTyxhQUFhLENBQUUsTUFBTSxJQUFJLFVBQVUsQ0FBQyxHQUFHLGNBQWMsVUFBVSxJQUFJLEtBQUssT0FBTztBQUFBO0FBT3hGLFlBQU0sQ0FBRSxNQUFNLGNBQWUsTUFBTSxRQUFRLFVBQVUsT0FBTyx3QkFBd0I7QUFBQSxRQUNsRixRQUFRLFVBQVUsS0FBSyxRQUFRO0FBQUEsUUFDL0IsS0FBSztBQUFBLFFBQ0wsWUFBWTtBQUFBLFFBQ1osYUFBYTtBQUFBO0FBRWYsVUFBSSxVQUFxQztBQUN6QyxVQUFJLFNBQVMsS0FBSyxhQUFhO0FBQzdCLFlBQUksQ0FBQyxLQUFLLFFBQVEsTUFBTTtBQUN4QixrQkFBVTtBQUFBO0FBRVosVUFBSTtBQUNKLFVBQUksUUFBUSxTQUFTLEdBQUc7QUFDdEIsaUJBQVMsQ0FBRSxHQUFHLFNBQVUsU0FBUztBQUMvQixnQkFBTSxNQUFNLFFBQVEsYUFBYTtBQUNqQyxjQUFJLENBQUM7QUFBSztBQUNWLGNBQUksY0FBYyxJQUFJLElBQUksT0FBTztBQUMvQiwyQkFBZSxJQUFJO0FBQ25CO0FBQUE7QUFBQTtBQUFBO0FBTU4sVUFBSSxDQUFDLGNBQWM7QUFDakIsY0FBTSxZQUFZLEtBQUssTUFBTSwwQkFBMEI7QUFDdkQsbUJBQVcsV0FBVyxXQUFXO0FBQy9CLGdCQUFNLENBQUMsR0FBRyxPQUFPLFFBQVEsTUFBTSwrQkFBK0I7QUFDOUQsY0FBSSxLQUFLO0FBQ1AsMkJBQWU7QUFDZjtBQUFBO0FBQUE7QUFBQTtBQU1OLFVBQUksY0FBYztBQUNoQixjQUFNLGNBQWMsY0FBYyxJQUFJO0FBRXRDLFlBQUksQ0FBQyxhQUFhO0FBQ2hCLGdCQUFNLFNBQVMsWUFBWSxHQUFHLE9BQU8sT0FBTyxpQ0FBaUMsZ0RBQWdEO0FBQzdILGlCQUFPO0FBQUE7QUFFVCxlQUFPLGFBQWEsQ0FBRSxNQUFNLElBQUksVUFBVSxjQUFjLElBQUksZUFBMkIsS0FBSyxPQUFPO0FBQUE7QUFJckcsWUFBTSxrQkFBa0IsQ0FBQyxHQUFHLGNBQWMsUUFBUTtBQUNsRCxZQUNFLFNBQ0EsWUFDQSxHQUFHLE9BQU8sT0FBTztBQUFBO0FBQUEsTUFFbkIsT0FBTyxLQUFLLGtCQUFrQixvQkFBb0IsV0FBVywyQkFBMkIsT0FBTyxLQUFLLHVCQUF1QjtBQUFBO0FBRzNILGFBQU87QUFBQTtBQUFBO0FBQUE7QUFNYixtQkFBbUIsU0FBaUM7QUFDbEQsU0FBTyxRQUFRLE9BQU87QUFBQTtBQUl4QixnQ0FBZ0MsZUFBeUQ7QUFDdkYsUUFBTSxZQUFZLElBQUk7QUFDdEIsUUFBTSxRQUFRLElBQ1osY0FBYyxJQUFJLENBQUMsU0FDakIsT0FBTyxNQUFNLEtBQUssQ0FBQyxDQUFFLFNBQVMsY0FBZTtBQUMzQyxRQUFJLENBQUMsU0FBUztBQUFpQjtBQUMvQixjQUFVLElBQUksU0FBUyxpQkFBaUI7QUFBQTtBQUk5QyxTQUFPO0FBQUE7QUFXVCw0QkFBNEIsQ0FBRSxNQUFNLElBQUksS0FBSyxXQUEyRDtBQUN0RyxRQUFNLENBQUUsdUJBQXdCO0FBQ2hDLFFBQU0sVUFBVSxNQUFNLG9CQUFxQixDQUFFLE9BQU8sT0FBTztBQUMzRCxRQUFNLFNBQVMsTUFBTSxJQUFJLFFBQXNDLENBQUMsU0FBUyxXQUFXO0FBQ2xGLFVBQU0sVUFBVSxDQUFDLEdBQUksUUFBUSxXQUFXO0FBQ3hDLFVBQU0sVUFDSixNQUNBO0FBQUEsTUFDRSxTQUFTLFFBQVE7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsS0FBSyxRQUFRO0FBQUEsTUFDYixVQUFVO0FBQUEsTUFDVixLQUFLO0FBQUEsTUFDTCxTQUFTO0FBQUEsTUFDVCxZQUFZO0FBQUEsTUFDWixZQUFZO0FBQUEsTUFDWixTQUFTO0FBQUEsT0FFWCxDQUFDLEtBQUssUUFBUTtBQUNaLFVBQUksS0FBSztBQUNQLGVBQU87QUFBQSxhQUNGO0FBQ0wsZUFBTyxRQUFRO0FBQUE7QUFBQTtBQUFBO0FBS3ZCLE1BQUksQ0FBQztBQUFRLFdBQU87QUFDcEIsU0FBTztBQUFBLElBQ0wsTUFBTSxPQUFPLFFBQVE7QUFBQSxJQUNyQixLQUFLLE9BQU87QUFBQTtBQUFBOyIsCiAgIm5hbWVzIjogW10KfQo=
