import { transformAsync } from "@babel/core"; // @ts-expect-error - no types import solid from "babel-preset-solid"; import { type BunPlugin, plugin as registerBunPlugin } from "bun"; let installed = false; function stripQueryHash(p: string): string { return p.split("?")[0]?.split("#")[0] ?? p; } export function createSolidTransformPlugin(): BunPlugin { return { name: "bun-plugin-solid", setup(build) { // Solid 2.0 resolves to server.js under Bun's "node" condition. // Redirect to solid.js (client/universal runtime) instead. build.onLoad( { filter: /[/\\]node_modules[/\\]solid-js[/\\]dist[/\\]server\.js(?:[?#].*)?$/, }, async (args) => { const path = stripQueryHash(args.path).replace( "server.js", "solid.js", ); return { contents: await Bun.file(path).text(), loader: "js" }; }, ); build.onLoad( { filter: /[/\\]node_modules[/\\]solid-js[/\\]store[/\\]dist[/\\]server\.js(?:[?#].*)?$/, }, async (args) => { const path = stripQueryHash(args.path).replace( "server.js", "store.js", ); return { contents: await Bun.file(path).text(), loader: "js" }; }, ); // Transform .tsx/.jsx through babel-preset-solid in universal mode build.onLoad({ filter: /\.(js|ts)x(?:[?#].*)?$/ }, async (args) => { const path = stripQueryHash(args.path); const code = await Bun.file(path).text(); const result = await transformAsync(code, { filename: path, configFile: false, babelrc: false, parserOpts: { plugins: ["typescript", "jsx"], }, presets: [ [ solid, { moduleName: "ashlar", generate: "universal", }, ], ], }); // Return as tsx — Bun strips types natively (much faster than babel) return { contents: result?.code ?? "", loader: "tsx" }; }); }, }; } export function ensureSolidTransformPlugin(): boolean { if (installed) return false; registerBunPlugin(createSolidTransformPlugin()); installed = true; return true; }