109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
import { Quadrant, Ring } from "@/lib/types";
|
||
|
||
export enum ErrorType {
|
||
NoQuadrant = "Item {0} has no quadrant or ring",
|
||
InvalidQuadrant = "Item {0} has invalid quadrant {1}\n\tvalid quadrants are: {2}",
|
||
InvalidRing = "Item {0} has invalid ring {1}\n\tvalid rings are: {2}",
|
||
NoRadarItems = "No valid radar items found. Please check the markdown files in the `radar` directory.",
|
||
}
|
||
|
||
export enum TextColor {
|
||
Default = 0,
|
||
Black,
|
||
Red = 31,
|
||
Green = 32,
|
||
Yellow = 33,
|
||
Blue = 34,
|
||
Mangenta = 35,
|
||
Cyan = 36,
|
||
White = 37,
|
||
}
|
||
|
||
export default class ErrorHandler {
|
||
private buildErrors: string[] = [];
|
||
private quadrants: Quadrant[];
|
||
private rings: Ring[];
|
||
private isStrict: boolean;
|
||
private supportsColor: boolean;
|
||
|
||
constructor(quadrants: Quadrant[], rings: Ring[]) {
|
||
this.isStrict = process.argv.slice(2).includes("--strict");
|
||
this.supportsColor = process.stdout.isTTY && process.env.TERM !== "dumb";
|
||
this.quadrants = quadrants;
|
||
this.rings = rings;
|
||
console.log(`ℹ️ Build is${this.isStrict ? "" : " not"} in strict mode\n`);
|
||
}
|
||
|
||
public processBuildErrors(errorType: ErrorType, ...args: string[]) {
|
||
const errorHint = this.getErrorHint(errorType);
|
||
const errorMsg = this.formatString(
|
||
errorType.toString(),
|
||
errorHint ? [...args, errorHint] : args,
|
||
);
|
||
this.buildErrors.push(errorMsg);
|
||
}
|
||
|
||
public checkForBuildErrors(exitOnErr: boolean = false) {
|
||
if (this.buildErrors.length > 0) {
|
||
console.warn(
|
||
this.colorizeBackground(
|
||
`There ${this.buildErrors.length > 1 ? "are" : "is"} ${this.buildErrors.length} error${this.buildErrors.length > 1 ? "s" : ""} in your data build`,
|
||
TextColor.Red,
|
||
) +
|
||
"\n\n" +
|
||
this.buildErrors
|
||
.map((error, index) => `${index + 1}. ${error}`)
|
||
.join("\n") +
|
||
"\n",
|
||
);
|
||
|
||
if (this.isStrict || exitOnErr) {
|
||
process.exit(1);
|
||
}
|
||
|
||
this.buildErrors = [];
|
||
}
|
||
}
|
||
|
||
private getErrorHint(errorType: ErrorType) {
|
||
switch (errorType) {
|
||
case ErrorType.InvalidQuadrant:
|
||
return this.quadrants.map((quadrant) => quadrant.id).join(", ");
|
||
case ErrorType.InvalidRing:
|
||
return this.rings.map((ring) => ring.id).join(", ");
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
public colorizeBackground(str: string, backgroundColor: TextColor) {
|
||
if (this.supportsColor) {
|
||
return `\x1b[${backgroundColor + 10}m${str}\x1b[${TextColor.Default}m`;
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
private formatString(msg: string, inserts: string[]) {
|
||
return inserts.reduce(
|
||
(acc, cur, index) =>
|
||
acc.replaceAll(
|
||
`{${index}}`,
|
||
this.colorizeString(
|
||
cur,
|
||
index === 2 ? TextColor.Green : TextColor.Red,
|
||
),
|
||
),
|
||
msg,
|
||
);
|
||
}
|
||
|
||
private colorizeString(str: string, textColor: TextColor) {
|
||
if (this.supportsColor) {
|
||
return `\x1b[${textColor}m${str}\x1b[${TextColor.Default}m`;
|
||
}
|
||
|
||
return str;
|
||
}
|
||
}
|