"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.preact = void 0;
const vite_1 = __importDefault(require("@prefresh/vite"));
const devtools_js_1 = require("./devtools.js");
const utils_js_1 = require("./utils.js");
const vite_prerender_plugin_1 = require("vite-prerender-plugin");
const core_1 = require("@babel/core");
// @ts-ignore package doesn't ship with declaration files
const plugin_transform_react_jsx_1 = __importDefault(require("@babel/plugin-transform-react-jsx"));
// @ts-ignore package doesn't ship with declaration files
const plugin_transform_react_jsx_development_1 = __importDefault(require("@babel/plugin-transform-react-jsx-development"));
// @ts-ignore package doesn't ship with declaration files
const babel_plugin_transform_hook_names_1 = __importDefault(require("babel-plugin-transform-hook-names"));
// Taken from https://github.com/vitejs/vite/blob/main/packages/plugin-react/src/index.ts
function preactPlugin({ devtoolsInProd, devToolsEnabled, prefreshEnabled, reactAliasesEnabled, prerender, include, exclude, babel, jsxImportSource, } = {}) {
    var _a;
    const baseParserOptions = [
        "importMeta",
        "explicitResourceManagement",
        "topLevelAwait",
    ];
    let config;
    let babelOptions = {
        babelrc: false,
        configFile: false,
        ...babel,
    };
    babelOptions.plugins || (babelOptions.plugins = []);
    babelOptions.presets || (babelOptions.presets = []);
    babelOptions.overrides || (babelOptions.overrides = []);
    babelOptions.parserOpts || (babelOptions.parserOpts = {});
    (_a = babelOptions.parserOpts).plugins || (_a.plugins = []);
    let useBabel = typeof babel !== "undefined";
    const shouldTransform = (0, utils_js_1.createFilter)(include || [/\.[cm]?[tj]sx?$/], exclude || [/node_modules/]);
    devtoolsInProd = devtoolsInProd !== null && devtoolsInProd !== void 0 ? devtoolsInProd : false;
    prefreshEnabled = prefreshEnabled !== null && prefreshEnabled !== void 0 ? prefreshEnabled : true;
    reactAliasesEnabled = reactAliasesEnabled !== null && reactAliasesEnabled !== void 0 ? reactAliasesEnabled : true;
    prerender = prerender !== null && prerender !== void 0 ? prerender : { enabled: false };
    const prerenderPlugin = (0, vite_prerender_plugin_1.vitePrerenderPlugin)(prerender);
    if (!prerender.previewMiddlewareEnabled) {
        const idx = prerenderPlugin.findIndex(p => p.name == "serve-prerendered-html");
        if (idx > -1) {
            prerenderPlugin.splice(idx, 1);
        }
    }
    const jsxPlugin = {
        name: "vite:preact-jsx",
        enforce: "pre",
        config() {
            return {
                build: {
                    rollupOptions: {
                        onwarn(warning, warn) {
                            // Silence Rollup's module-level directive warnings re:"use client".
                            // They're likely to come from `node_modules` and won't be actionable.
                            if (warning.code === "MODULE_LEVEL_DIRECTIVE" &&
                                warning.message.includes("use client"))
                                return;
                            // ESBuild seemingly doesn't include mappings for directives, causing
                            // Rollup to emit warnings about missing source locations. This too is
                            // likely to come from `node_modules` and won't be actionable.
                            // evanw/esbuild#3548
                            if (warning.code === "SOURCEMAP_ERROR" &&
                                warning.message.includes("resolve original location") &&
                                warning.pos === 0)
                                return;
                            warn(warning);
                        },
                    },
                },
                esbuild: useBabel
                    ? undefined
                    : {
                        jsx: "automatic",
                        jsxImportSource: jsxImportSource !== null && jsxImportSource !== void 0 ? jsxImportSource : "preact",
                    },
                optimizeDeps: {
                    include: ["preact", "preact/jsx-runtime", "preact/jsx-dev-runtime"],
                },
            };
        },
        configResolved(resolvedConfig) {
            config = resolvedConfig;
            devToolsEnabled =
                devToolsEnabled !== null && devToolsEnabled !== void 0 ? devToolsEnabled : (!config.isProduction || devtoolsInProd);
            useBabel || (useBabel = !config.isProduction || !!devToolsEnabled);
        },
        async transform(code, url) {
            // Ignore query parameters, as in Vue SFC virtual modules.
            const { id } = (0, utils_js_1.parseId)(url);
            if (!useBabel || !shouldTransform(id))
                return;
            const parserPlugins = [
                ...baseParserOptions,
                "classProperties",
                "classPrivateProperties",
                "classPrivateMethods",
                !id.endsWith(".ts") && "jsx",
                /\.tsx?$/.test(id) && "typescript",
            ].filter(Boolean);
            const result = await (0, core_1.transformAsync)(code, {
                ...babelOptions,
                ast: true,
                root: config.root,
                filename: id,
                parserOpts: {
                    ...babelOptions.parserOpts,
                    sourceType: "module",
                    allowAwaitOutsideFunction: true,
                    plugins: parserPlugins,
                },
                generatorOpts: {
                    ...babelOptions.generatorOpts,
                    decoratorsBeforeExport: true,
                },
                plugins: [
                    ...babelOptions.plugins,
                    [
                        config.isProduction ? plugin_transform_react_jsx_1.default : plugin_transform_react_jsx_development_1.default,
                        {
                            runtime: "automatic",
                            importSource: jsxImportSource !== null && jsxImportSource !== void 0 ? jsxImportSource : "preact",
                        },
                    ],
                    ...(devToolsEnabled ? [babel_plugin_transform_hook_names_1.default] : []),
                ],
                sourceMaps: true,
                inputSourceMap: false,
            });
            // NOTE: Since no config file is being loaded, this path wouldn't occur.
            if (!result)
                return;
            return {
                code: result.code || code,
                map: result.map,
            };
        },
    };
    return [
        ...(reactAliasesEnabled
            ? [
                {
                    name: "preact:config",
                    config() {
                        return {
                            resolve: {
                                alias: {
                                    "react-dom/test-utils": "preact/test-utils",
                                    "react-dom": "preact/compat",
                                    react: "preact/compat",
                                },
                            },
                        };
                    },
                },
            ]
            : []),
        jsxPlugin,
        (0, devtools_js_1.preactDevtoolsPlugin)({
            devtoolsInProd,
            devToolsEnabled,
            shouldTransform,
        }),
        ...(prefreshEnabled
            ? [(0, vite_1.default)({ include, exclude, parserPlugins: baseParserOptions })]
            : []),
        ...(prerender.enabled ? prerenderPlugin : []),
    ];
}
exports.preact = preactPlugin;
exports.default = preactPlugin;
