mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-08 22:50:00 +08:00
* split ts files * packages * nomore workspace? * blah * build, exports * declaration * blargh * turrrrbo * fix fontawesome paths * allow file in eslint, fix ts errors * optimise package, update tsconfig * fix ts * update turbo config * eslint split * fix imports * fix types * lock * add turbo task * script * test task * pretty scripts * update prettier ignore * no cache for tests * lint task * turbo * no out * depend on env * fix mono breaking things * odl * fix version dependency of mongodb-memory-server * Revert "fix version dependency of mongodb-memory-server" This reverts commit52ffac47b1
. * update vitest-mongodb * release scripts * update ci * update dev script * ignore issues around firebase config * add check ts tasks * import isaxioserror * shared types package * replace tsnodedev with tsx * fix import * shared types * module * backend imports * declaration * node version * test code * assert json * verbatim * type * lodash * ts ver * fix fix fix? * remove assert * remove module and resolution * cleanup * tsconfig * fix frontend * remove unecessary props * more unused * remove skiplib * declaration map, dev script * remove install scripts * fix regex * move shared types to package * dont include shared types * remove path * update scripts * test code * test code * fix backend types * fully fix backend * fix frontend d.ts * add .js to imports * remove module * revert add .js * update tsconfig * use bundler module resolution * almost all frontend types * mooore * date fns * fix backend docker * fix ape keys * fix type * clean rimraf type * fix shared-types in workspace * fix import resolving * fix docker builds * ignore type problems on slim-select until new version is released * turrrrbo * fix npm ci * fix lint task * expose env variables needed by frontend build * fix dependencies * package-lock * backend watch ts and lint * add fe and be build scripts to root * fix dev not building packages * shared-types missing eslint * move shared types back to dev-deps * add packages to labeler * add packages step to ci * typo * filter update * remove concurrently from root * add scripts * abbreviate * rename * yeet * fixed path * test pkg * consistent ordering * rename * Revert "backend imports" This reverts commitd715198829
. * fix missing imports, remove last .js * remove test package --------- Co-authored-by: Christian Fehmer <cfe@sexy-developer.com>
173 lines
4.3 KiB
TypeScript
173 lines
4.3 KiB
TypeScript
import * as fs from "fs";
|
|
import { createRequire } from "module";
|
|
import * as path from "path";
|
|
|
|
type FontawesomeConfig = {
|
|
/* used regular icons without `fa-` prefix*/
|
|
regular: string[];
|
|
/* used solid icons without `fa-` prefix*/
|
|
solid: string[];
|
|
/* used brands icons without `fa-` prefix*/
|
|
brands: string[];
|
|
};
|
|
|
|
type FileObject = { name: string; isDirectory: boolean };
|
|
|
|
const iconSet = {
|
|
solid: parseIcons("solid"),
|
|
regular: parseIcons("regular"),
|
|
brands: parseIcons("brands"),
|
|
};
|
|
/**
|
|
* Map containing reserved classes by module
|
|
*/
|
|
const modules2 = {
|
|
animated: ["spin", "pulse"],
|
|
"bordererd-pulled": ["border", "pull-left", "pull-right"],
|
|
"fixed-width": ["fw"],
|
|
larger: [
|
|
"lg",
|
|
"xs",
|
|
"sm",
|
|
"1x",
|
|
"2x",
|
|
"3x",
|
|
"4x",
|
|
"5x",
|
|
"6x",
|
|
"7x",
|
|
"8x",
|
|
"9x",
|
|
"10x",
|
|
],
|
|
"rotated-flipped": [
|
|
"rotate-90",
|
|
"rotate-180",
|
|
"rotate-270",
|
|
"flip-horizontal",
|
|
"flip-vertical",
|
|
"flip-both",
|
|
],
|
|
stacked: ["stack", "stack-1x", "stack-2x", "inverse"],
|
|
};
|
|
|
|
/**
|
|
* Detect used fontawesome icons in the directories `src/**` and `static/**{.html|.css}`
|
|
* @param {boolean} debug - Enable debug output
|
|
* @returns {FontawesomeConfig} - used icons
|
|
*/
|
|
|
|
export function getFontawesomeConfig(debug = false): FontawesomeConfig {
|
|
const time = Date.now();
|
|
const srcFiles = findAllFiles(
|
|
"./src",
|
|
(filename) =>
|
|
!filename.endsWith("fontawesome-5.scss") &&
|
|
!filename.endsWith("fontawesome-6.scss") //ignore our own css
|
|
);
|
|
const staticFiles = findAllFiles(
|
|
"./static",
|
|
(filename) => filename.endsWith(".html") || filename.endsWith(".css")
|
|
);
|
|
|
|
const allFiles = [...srcFiles, ...staticFiles];
|
|
const usedClassesSet: Set<string> = new Set();
|
|
|
|
const regex = /\bfa-[a-z0-9-]+\b/g;
|
|
|
|
for (const file of allFiles) {
|
|
const fileContent = fs.readFileSync("./" + file).toString();
|
|
const matches = fileContent.match(regex);
|
|
|
|
if (matches) {
|
|
matches.forEach((match) => {
|
|
const [icon] = match.split(" ");
|
|
usedClassesSet.add((icon as string).substring(3));
|
|
});
|
|
}
|
|
}
|
|
|
|
const usedClasses = new Array(...usedClassesSet).sort();
|
|
const allModuleClasses = Object.values(modules2).flatMap((it) => it);
|
|
const icons = usedClasses.filter((it) => !allModuleClasses.includes(it));
|
|
|
|
const solid = icons.filter((it) => iconSet.solid.includes(it));
|
|
const regular = icons.filter((it) => iconSet.regular.includes(it));
|
|
const brands = usedClasses.filter((it) => iconSet.brands.includes(it));
|
|
|
|
const leftOvers = icons.filter(
|
|
(it) => !(solid.includes(it) || regular.includes(it) || brands.includes(it))
|
|
);
|
|
if (leftOvers.length !== 0) {
|
|
throw new Error("unknown icons: " + leftOvers);
|
|
}
|
|
|
|
if (debug === true) {
|
|
console.debug(
|
|
"Make sure fontawesome modules are active: ",
|
|
Object.entries(modules2)
|
|
.filter((it) => usedClasses.filter((c) => it[1].includes(c)).length > 0)
|
|
.map((it) => it[0])
|
|
.filter((it) => it !== "brands")
|
|
.join(", ")
|
|
);
|
|
|
|
console.debug(
|
|
"Here is your config: \n",
|
|
JSON.stringify({
|
|
regular,
|
|
solid,
|
|
brands,
|
|
})
|
|
);
|
|
console.debug("Detected fontawesome classes in", Date.now() - time, "ms");
|
|
}
|
|
|
|
return {
|
|
regular,
|
|
solid,
|
|
brands,
|
|
};
|
|
}
|
|
|
|
//detect if we run this as a main
|
|
if (import.meta.url.endsWith(process.argv[1] as string)) {
|
|
getFontawesomeConfig(true);
|
|
}
|
|
|
|
function toFileAndDir(dir: string, file: string): FileObject {
|
|
const name = path.join(dir, file);
|
|
return { name, isDirectory: fs.statSync(name).isDirectory() };
|
|
}
|
|
|
|
function findAllFiles(
|
|
dir: string,
|
|
filter: (filename: string) => boolean = (_it): boolean => true
|
|
): string[] {
|
|
const files = fs
|
|
.readdirSync(dir)
|
|
.map((it) => toFileAndDir(dir, it))
|
|
.filter((file) => file.isDirectory || filter(file.name));
|
|
|
|
const out: string[] = [];
|
|
for (const file of files) {
|
|
if (file.isDirectory) {
|
|
out.push(...findAllFiles(file.name, filter));
|
|
} else {
|
|
out.push(file.name);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function parseIcons(iconSet: string): string[] {
|
|
const require = createRequire(import.meta.url);
|
|
const path = require.resolve(
|
|
`@fortawesome/fontawesome-free/js/${iconSet}.js`
|
|
);
|
|
const file: string | null = fs.readFileSync(path).toString();
|
|
|
|
return file
|
|
?.match(/"(.*)": \[.*\],/g)
|
|
?.map((it) => it.substring(1, it.indexOf(":") - 1)) as string[];
|
|
}
|