mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 13:59:16 +01:00
refactor: 🚨 Turn every linter rule on and fix issues (there were a LOT :3)
This commit is contained in:
parent
2e98859153
commit
a1e02d0d78
177 changed files with 1826 additions and 1248 deletions
|
|
@ -5,19 +5,19 @@ import chalk from "chalk";
|
|||
import { config } from "config-manager";
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = "debug",
|
||||
INFO = "info",
|
||||
WARNING = "warning",
|
||||
ERROR = "error",
|
||||
CRITICAL = "critical",
|
||||
Debug = "debug",
|
||||
Info = "info",
|
||||
Warning = "warning",
|
||||
Error = "error",
|
||||
Critical = "critical",
|
||||
}
|
||||
|
||||
const logOrder = [
|
||||
LogLevel.DEBUG,
|
||||
LogLevel.INFO,
|
||||
LogLevel.WARNING,
|
||||
LogLevel.ERROR,
|
||||
LogLevel.CRITICAL,
|
||||
LogLevel.Debug,
|
||||
LogLevel.Info,
|
||||
LogLevel.Warning,
|
||||
LogLevel.Error,
|
||||
LogLevel.Critical,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -37,15 +37,15 @@ export class LogManager {
|
|||
|
||||
getLevelColor(level: LogLevel) {
|
||||
switch (level) {
|
||||
case LogLevel.DEBUG:
|
||||
case LogLevel.Debug:
|
||||
return chalk.blue;
|
||||
case LogLevel.INFO:
|
||||
case LogLevel.Info:
|
||||
return chalk.green;
|
||||
case LogLevel.WARNING:
|
||||
case LogLevel.Warning:
|
||||
return chalk.yellow;
|
||||
case LogLevel.ERROR:
|
||||
case LogLevel.Error:
|
||||
return chalk.red;
|
||||
case LogLevel.CRITICAL:
|
||||
case LogLevel.Critical:
|
||||
return chalk.bgRed;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,8 +79,9 @@ export class LogManager {
|
|||
if (
|
||||
logOrder.indexOf(level) <
|
||||
logOrder.indexOf(config.logging.log_level as LogLevel)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.enableColors) {
|
||||
await this.write(
|
||||
|
|
@ -102,9 +103,8 @@ export class LogManager {
|
|||
}
|
||||
|
||||
private async write(text: string) {
|
||||
Bun.stdout.name;
|
||||
if (this.output === Bun.stdout) {
|
||||
await console.log(`${text}`);
|
||||
console.info(text);
|
||||
} else {
|
||||
if (!(await exists(this.output.name ?? ""))) {
|
||||
// Create file if it doesn't exist
|
||||
|
|
@ -128,17 +128,112 @@ export class LogManager {
|
|||
* @param error Error to log
|
||||
*/
|
||||
async logError(level: LogLevel, entity: string, error: Error) {
|
||||
error.stack && (await this.log(LogLevel.DEBUG, entity, error.stack));
|
||||
error.stack && (await this.log(LogLevel.Debug, entity, error.stack));
|
||||
await this.log(level, entity, error.message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the headers of a request
|
||||
* @param req Request to log
|
||||
*/
|
||||
public logHeaders(req: Request): string {
|
||||
let string = " [Headers]\n";
|
||||
for (const [key, value] of req.headers.entries()) {
|
||||
string += ` ${key}: ${value}\n`;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the body of a request
|
||||
* @param req Request to log
|
||||
*/
|
||||
async logBody(req: Request): Promise<string> {
|
||||
let string = " [Body]\n";
|
||||
const contentType = req.headers.get("Content-Type");
|
||||
|
||||
if (contentType?.includes("application/json")) {
|
||||
string += await this.logJsonBody(req);
|
||||
} else if (
|
||||
contentType &&
|
||||
(contentType.includes("application/x-www-form-urlencoded") ||
|
||||
contentType.includes("multipart/form-data"))
|
||||
) {
|
||||
string += await this.logFormData(req);
|
||||
} else {
|
||||
const text = await req.text();
|
||||
string += ` ${text}\n`;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the JSON body of a request
|
||||
* @param req Request to log
|
||||
*/
|
||||
async logJsonBody(req: Request): Promise<string> {
|
||||
let string = "";
|
||||
try {
|
||||
const json = await req.clone().json();
|
||||
const stringified = JSON.stringify(json, null, 4)
|
||||
.split("\n")
|
||||
.map((line) => ` ${line}`)
|
||||
.join("\n");
|
||||
|
||||
string += `${stringified}\n`;
|
||||
} catch {
|
||||
string += ` [Invalid JSON] (raw: ${await req.clone().text()})\n`;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the form data of a request
|
||||
* @param req Request to log
|
||||
*/
|
||||
async logFormData(req: Request): Promise<string> {
|
||||
let string = "";
|
||||
const formData = await req.clone().formData();
|
||||
for (const [key, value] of formData.entries()) {
|
||||
if (value.toString().length < 300) {
|
||||
string += ` ${key}: ${value.toString()}\n`;
|
||||
} else {
|
||||
string += ` ${key}: <${value.toString().length} bytes>\n`;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a request to the output
|
||||
* @param req Request to log
|
||||
* @param ip IP of the request
|
||||
* @param logAllDetails Whether to log all details of the request
|
||||
*/
|
||||
async logRequest(req: Request, ip?: string, logAllDetails = false) {
|
||||
async logRequest(
|
||||
req: Request,
|
||||
ip?: string,
|
||||
logAllDetails = false,
|
||||
): Promise<void> {
|
||||
let string = ip ? `${ip}: ` : "";
|
||||
|
||||
string += `${req.method} ${req.url}`;
|
||||
|
||||
if (logAllDetails) {
|
||||
string += "\n";
|
||||
string += await this.logHeaders(req);
|
||||
string += await this.logBody(req);
|
||||
}
|
||||
await this.log(LogLevel.Info, "Request", string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Logs a request to the output
|
||||
* @param req Request to log
|
||||
* @param ip IP of the request
|
||||
* @param logAllDetails Whether to log all details of the request
|
||||
*/
|
||||
/**async logRequest(req: Request, ip?: string, logAllDetails = false) {
|
||||
let string = ip ? `${ip}: ` : "";
|
||||
|
||||
string += `${req.method} ${req.url}`;
|
||||
|
|
@ -153,9 +248,9 @@ export class LogManager {
|
|||
|
||||
// Pretty print body
|
||||
string += " [Body]\n";
|
||||
const content_type = req.headers.get("Content-Type");
|
||||
const contentType = req.headers.get("Content-Type");
|
||||
|
||||
if (content_type?.includes("application/json")) {
|
||||
if (contentType?.includes("application/json")) {
|
||||
try {
|
||||
const json = await req.clone().json();
|
||||
const stringified = JSON.stringify(json, null, 4)
|
||||
|
|
@ -170,9 +265,9 @@ export class LogManager {
|
|||
.text()})\n`;
|
||||
}
|
||||
} else if (
|
||||
content_type &&
|
||||
(content_type.includes("application/x-www-form-urlencoded") ||
|
||||
content_type.includes("multipart/form-data"))
|
||||
contentType &&
|
||||
(contentType.includes("application/x-www-form-urlencoded") ||
|
||||
contentType.includes("multipart/form-data"))
|
||||
) {
|
||||
const formData = await req.clone().formData();
|
||||
for (const [key, value] of formData.entries()) {
|
||||
|
|
@ -189,8 +284,8 @@ export class LogManager {
|
|||
string += ` ${text}\n`;
|
||||
}
|
||||
}
|
||||
await this.log(LogLevel.INFO, "Request", string);
|
||||
}
|
||||
await this.log(LogLevel.Info, "Request", string);
|
||||
} */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ describe("LogManager", () => {
|
|||
});
|
||||
*/
|
||||
it("should log message with timestamp", async () => {
|
||||
await logManager.log(LogLevel.INFO, "TestEntity", "Test message");
|
||||
await logManager.log(LogLevel.Info, "TestEntity", "Test message");
|
||||
expect(mockAppend).toHaveBeenCalledWith(
|
||||
mockOutput.name,
|
||||
expect.stringContaining("[INFO] TestEntity: Test message"),
|
||||
|
|
@ -45,7 +45,7 @@ describe("LogManager", () => {
|
|||
|
||||
it("should log message without timestamp", async () => {
|
||||
await logManager.log(
|
||||
LogLevel.INFO,
|
||||
LogLevel.Info,
|
||||
"TestEntity",
|
||||
"Test message",
|
||||
false,
|
||||
|
|
@ -56,9 +56,10 @@ describe("LogManager", () => {
|
|||
);
|
||||
});
|
||||
|
||||
// biome-ignore lint/suspicious/noSkippedTests: I need to fix this :sob:
|
||||
test.skip("should write to stdout", async () => {
|
||||
logManager = new LogManager(Bun.stdout);
|
||||
await logManager.log(LogLevel.INFO, "TestEntity", "Test message");
|
||||
await logManager.log(LogLevel.Info, "TestEntity", "Test message");
|
||||
|
||||
const writeMock = jest.fn();
|
||||
|
||||
|
|
@ -75,7 +76,7 @@ describe("LogManager", () => {
|
|||
|
||||
it("should log error message", async () => {
|
||||
const error = new Error("Test error");
|
||||
await logManager.logError(LogLevel.ERROR, "TestEntity", error);
|
||||
await logManager.logError(LogLevel.Error, "TestEntity", error);
|
||||
expect(mockAppend).toHaveBeenCalledWith(
|
||||
mockOutput.name,
|
||||
expect.stringContaining("[ERROR] TestEntity: Test error"),
|
||||
|
|
@ -191,10 +192,10 @@ describe("MultiLogManager", () => {
|
|||
});
|
||||
|
||||
it("should log message to all logManagers", async () => {
|
||||
await multiLogManager.log(LogLevel.INFO, "TestEntity", "Test message");
|
||||
await multiLogManager.log(LogLevel.Info, "TestEntity", "Test message");
|
||||
expect(mockLog).toHaveBeenCalledTimes(2);
|
||||
expect(mockLog).toHaveBeenCalledWith(
|
||||
LogLevel.INFO,
|
||||
LogLevel.Info,
|
||||
"TestEntity",
|
||||
"Test message",
|
||||
true,
|
||||
|
|
@ -203,10 +204,10 @@ describe("MultiLogManager", () => {
|
|||
|
||||
it("should log error to all logManagers", async () => {
|
||||
const error = new Error("Test error");
|
||||
await multiLogManager.logError(LogLevel.ERROR, "TestEntity", error);
|
||||
await multiLogManager.logError(LogLevel.Error, "TestEntity", error);
|
||||
expect(mockLogError).toHaveBeenCalledTimes(2);
|
||||
expect(mockLogError).toHaveBeenCalledWith(
|
||||
LogLevel.ERROR,
|
||||
LogLevel.Error,
|
||||
"TestEntity",
|
||||
error,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue