import { plugin, type BunPlugin } from "bun"; import path from 'path'; const fontPlugin: BunPlugin = { name: "Font loader", async setup(build) { build.onResolve({ filter: /^__style_helper__$/ }, (args) => { return { path: args.path, namespace: 'style-helper', } }); build.onLoad({ filter: /.*/, namespace: 'style-helper' }, async () => { return { contents: ` export default function injectStyle(text) { if (typeof document !== 'undefined') { let styleTag = document.querySelector('style') if (!styleTag) { styleTag = document.createElement('style') document.head.appendChild(styleTag) } styleTag.appendChild(document.createTextNode(text)) } } `, loader: 'js', } }) build.onLoad({ filter: /\.font\.css$/ }, async (args) => { let css = await Bun.file(args.path).text(); const regex = /url\(['"]?(?!data:)([^'")]*)['"]?\)/; let match: RegExpExecArray | null = null; while ((match = regex.exec(css)) != null) { if (match?.[1]) { let buffer: Buffer | null = null; const fontName = match[1]; if (fontName.startsWith('http')) { const response = await fetch(fontName); if (response.ok) { buffer = Buffer.from(await response.arrayBuffer()); } } else { const fontPath = path.resolve(path.dirname(args.path), fontName); const fontFile = Bun.file(fontPath); if (await fontFile.exists()) { buffer = Buffer.from(await fontFile.arrayBuffer()); } } if (buffer) { const url = `data:;base64,${buffer.toString('base64')}`; css = css.replace(fontName, url); } } } const updatedCSS = css .replace(/(\n\s*)*/g, '') .replace(/;\s*\}/g, '}') .replace(/\s*([{:])\s*/g, '$1'); return { contents: `import i from '__style_helper__';i(${JSON.stringify(updatedCSS)})`, loader: 'js', }; }); } }; plugin(fontPlugin); export default fontPlugin;