| 1 | import * as NodeFSP from "node:fs/promises"; |
| 2 | import * as NodeModule from "node:module"; |
| 3 | import * as NodePath from "node:path"; |
| 4 | import * as NodeURL from "node:url"; |
| 5 | |
| 6 | import { compile } from "tailwindcss"; |
| 7 | |
| 8 | const directory = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)); |
| 9 | const appRoot = NodePath.join(directory, ".."); |
| 10 | const sourcePath = NodePath.join(appRoot, "src", "preview", "Annotation.css"); |
| 11 | const preloadPath = NodePath.join(appRoot, "src", "preview", "PickPreload.ts"); |
| 12 | const outputPath = NodePath.join(appRoot, "src", "preview", "AnnotationStyles.generated.ts"); |
| 13 | const require = NodeModule.createRequire(import.meta.url); |
| 14 | const tailwindRoot = NodePath.dirname(require.resolve("tailwindcss/package.json")); |
| 15 | |
| 16 | const [annotationSource, preloadSource, themeSource, preflightSource] = await Promise.all([ |
| 17 | NodeFSP.readFile(sourcePath, "utf8"), |
| 18 | NodeFSP.readFile(preloadPath, "utf8"), |
| 19 | NodeFSP.readFile(NodePath.join(tailwindRoot, "theme.css"), "utf8"), |
| 20 | NodeFSP.readFile(NodePath.join(tailwindRoot, "preflight.css"), "utf8"), |
| 21 | ]); |
| 22 | |
| 23 | const candidates = new Set( |
| 24 | Array.from(preloadSource.matchAll(/!?-?[A-Za-z0-9_:@/.[\]()%,-]+/g), (match) => match[0]), |
| 25 | ); |
| 26 | const compilerInput = [ |
| 27 | themeSource, |
| 28 | preflightSource, |
| 29 | annotationSource.replace('@import "tailwindcss";', "@tailwind utilities;"), |
| 30 | ].join("\n"); |
| 31 | const compiler = await compile(compilerInput, { base: appRoot }); |
| 32 | const css = compiler.build([...candidates]); |
| 33 | const encodedCss = `'${css |
| 34 | .replaceAll("\\", "\\\\") |
| 35 | .replaceAll("'", "\\'") |
| 36 | .replaceAll("\r", "\\r") |
| 37 | .replaceAll("\n", "\\n")}'`; |
| 38 | const moduleSource = `// Generated by scripts/build-preview-annotation-css.mjs. Do not edit.\nexport const previewAnnotationStyles =\n ${encodedCss};\n`; |
| 39 | |
| 40 | await NodeFSP.writeFile(outputPath, moduleSource); |