85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
|
import fs from "fs";
|
||
|
import path from "path";
|
||
|
import { fileURLToPath } from "url";
|
||
|
|
||
|
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||
|
|
||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||
|
function* walkFilesystem(dir: string): Generator<string, undefined, any> {
|
||
|
const openeddir = fs.opendirSync(dir);
|
||
|
if (!openeddir) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let d: fs.Dirent | null;
|
||
|
while ((d = openeddir?.readSync())) {
|
||
|
if (!d) {
|
||
|
break;
|
||
|
}
|
||
|
const entry = path.join(dir, d.name);
|
||
|
if (d.isDirectory()) yield* walkFilesystem(entry);
|
||
|
else if (d.isFile()) yield entry;
|
||
|
}
|
||
|
openeddir.close();
|
||
|
}
|
||
|
|
||
|
const import_re = /^(import \w+ from .*\.css)";/;
|
||
|
function extractImportLinesFromFile(path: string) {
|
||
|
const source = fs.readFileSync(path, { encoding: "utf8", flag: "r" });
|
||
|
const lines = source?.split("\n") ?? [];
|
||
|
return lines.filter((l) => import_re.test(l));
|
||
|
}
|
||
|
|
||
|
function createOneImportLine(line: string) {
|
||
|
const importMatch = import_re.exec(line);
|
||
|
if (!importMatch) {
|
||
|
throw new Error("How did an unmatchable line get here?");
|
||
|
}
|
||
|
const importContent = importMatch[1];
|
||
|
if (!importContent) {
|
||
|
throw new Error("How did an unmatchable line get here!?");
|
||
|
}
|
||
|
return `'${importContent}";': '${importContent}?inline";',`;
|
||
|
}
|
||
|
|
||
|
const isSourceFile = /\.ts$/;
|
||
|
function getTheSourceFiles() {
|
||
|
return Array.from(walkFilesystem(path.join(__dirname, "..", "src"))).filter((path) =>
|
||
|
isSourceFile.test(path),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function getTheImportLines(importPaths: string[]) {
|
||
|
const importLines: string[] = importPaths.reduce(
|
||
|
(acc: string[], path) => [...acc, extractImportLinesFromFile(path)].flat(),
|
||
|
[],
|
||
|
);
|
||
|
const uniqueImportLines = new Set(importLines);
|
||
|
const sortedImportLines = Array.from(uniqueImportLines.keys());
|
||
|
sortedImportLines.sort();
|
||
|
return sortedImportLines;
|
||
|
}
|
||
|
|
||
|
const importPaths = getTheSourceFiles();
|
||
|
const importLines = getTheImportLines(importPaths);
|
||
|
|
||
|
const outputFile = `
|
||
|
// THIS IS A GENERATED FILE. DO NOT EDIT BY HAND.
|
||
|
//
|
||
|
// This file is generated by the build-storybook-import-maps script in the UI's base directory.
|
||
|
// This is a *hack* to work around an inconsistency in the way rollup, vite, and storybook
|
||
|
// import CSS modules.
|
||
|
//
|
||
|
// Sometime around 2030 or so, the Javascript community may finally get its collective act together
|
||
|
// and we'll have one unified way of doing this. I can only hope.
|
||
|
|
||
|
export const cssImportMaps = {
|
||
|
${importLines.map(createOneImportLine).join("\n")}
|
||
|
};
|
||
|
`;
|
||
|
|
||
|
fs.writeFileSync(path.join(__dirname, "..", ".storybook", "css-import-maps.ts"), outputFile, {
|
||
|
encoding: "utf8",
|
||
|
flag: "w",
|
||
|
});
|