refactor: improve code quality
This commit is contained in:
@@ -2,10 +2,10 @@ import { defineConfig } from "drizzle-kit";
|
||||
import { env } from "~/env";
|
||||
|
||||
export default defineConfig({
|
||||
dialect: "postgresql",
|
||||
out: "./drizzle",
|
||||
schema: "./src/schema/index.ts",
|
||||
dbCredentials: {
|
||||
url: env.DATABASE_URL,
|
||||
},
|
||||
dialect: "postgresql",
|
||||
out: "./drizzle",
|
||||
schema: "./src/schema/index.ts",
|
||||
dbCredentials: {
|
||||
url: env.DATABASE_URL,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
{
|
||||
"name": "@lbf-bot/database",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
"name": "@lbf-bot/database",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"drizzle"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
||||
"check": "tsc --noEmit && eslint src/",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:studio": "drizzle-kit studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lbf-bot/utils": "workspace:*",
|
||||
"drizzle-orm": "0.44.7",
|
||||
"ioredis": "5.8.2",
|
||||
"pg": "8.16.3",
|
||||
"zod": "4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"drizzle-kit": "0.31.7",
|
||||
"tsc-alias": "1.8.16",
|
||||
"typescript": "5.9.3"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"drizzle"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:studio": "drizzle-kit studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lbf-bot/utils": "workspace:*",
|
||||
"drizzle-orm": "0.44.7",
|
||||
"ioredis": "5.8.2",
|
||||
"pg": "8.16.3",
|
||||
"zod": "4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"drizzle-kit": "0.31.7",
|
||||
"tsc-alias": "1.8.16",
|
||||
"typescript": "5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"removeComments": false
|
||||
},
|
||||
"tsc-alias": {
|
||||
"resolveFullPaths": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"removeComments": false
|
||||
},
|
||||
"tsc-alias": {
|
||||
"resolveFullPaths": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./src/*"],
|
||||
"~": ["./src/index"]
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"paths": {
|
||||
"~/*": ["./src/*"],
|
||||
"~": ["./src/index"]
|
||||
},
|
||||
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
},
|
||||
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
},
|
||||
"include": ["src", "drizzle.config.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
"include": ["src", "drizzle.config.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
{
|
||||
"name": "@lbf-bot/utils",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
"name": "@lbf-bot/utils",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
||||
"check": "tsc --noEmit && eslint src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "17.2.3",
|
||||
"zod": "4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "22.19.1",
|
||||
"tsc-alias": "1.8.16",
|
||||
"typescript": "5.9.3"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "17.2.3",
|
||||
"zod": "4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "22.19.1",
|
||||
"tsc-alias": "1.8.16",
|
||||
"typescript": "5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@ import "dotenv/config";
|
||||
import { z } from "zod";
|
||||
|
||||
export const parseEnv = <T extends z.ZodRawShape>(vars: T) => {
|
||||
const schema = z.object(vars);
|
||||
const result = schema.safeParse(process.env);
|
||||
if (!result.success) {
|
||||
console.error("ERROR: Environment variable validation failed:");
|
||||
for (const issue of result.error.issues) {
|
||||
console.error(`- ${issue.path.join(".")}: ${issue.message}`);
|
||||
const schema = z.object(vars);
|
||||
const result = schema.safeParse(process.env);
|
||||
if (!result.success) {
|
||||
console.error("ERROR: Environment variable validation failed:");
|
||||
for (const issue of result.error.issues) {
|
||||
console.error(`- ${issue.path.join(".")}: ${issue.message}`);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
return result.data;
|
||||
};
|
||||
|
||||
@@ -1,101 +1,96 @@
|
||||
type LogLevel = "debug" | "info" | "warn" | "error";
|
||||
|
||||
interface LoggerOptions {
|
||||
prefix?: string;
|
||||
level?: LogLevel;
|
||||
type LoggerOptions = {
|
||||
prefix?: string;
|
||||
level?: LogLevel;
|
||||
}
|
||||
|
||||
const LOG_LEVELS = {
|
||||
debug: 0,
|
||||
info: 1,
|
||||
warn: 2,
|
||||
error: 3,
|
||||
debug: 0,
|
||||
info: 1,
|
||||
warn: 2,
|
||||
error: 3,
|
||||
} as const satisfies Record<LogLevel, number>;
|
||||
|
||||
const COLORS = {
|
||||
debug: "\x1b[36m", // cyan
|
||||
info: "\x1b[32m", // green
|
||||
warn: "\x1b[33m", // yellow
|
||||
error: "\x1b[31m", // red
|
||||
reset: "\x1b[0m",
|
||||
gray: "\x1b[90m",
|
||||
bold: "\x1b[1m",
|
||||
debug: "\x1b[36m", // cyan
|
||||
info: "\x1b[32m", // green
|
||||
warn: "\x1b[33m", // yellow
|
||||
error: "\x1b[31m", // red
|
||||
reset: "\x1b[0m",
|
||||
gray: "\x1b[90m",
|
||||
bold: "\x1b[1m",
|
||||
} as const;
|
||||
|
||||
class Logger {
|
||||
private prefix: string;
|
||||
private minLevel: number;
|
||||
private prefix: string;
|
||||
private minLevel: number;
|
||||
|
||||
constructor(options: LoggerOptions = {}) {
|
||||
this.prefix = options.prefix || "";
|
||||
this.minLevel = LOG_LEVELS[options.level || "info"];
|
||||
}
|
||||
constructor(options: LoggerOptions = {}) {
|
||||
this.prefix = options.prefix || "";
|
||||
this.minLevel = LOG_LEVELS[options.level || "info"];
|
||||
}
|
||||
|
||||
private formatTimestamp(): string {
|
||||
const now = new Date();
|
||||
const hours = String(now.getHours()).padStart(2, "0");
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
const seconds = String(now.getSeconds()).padStart(2, "0");
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
private formatTimestamp(): string {
|
||||
const now = new Date();
|
||||
const hours = String(now.getHours()).padStart(2, "0");
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
const seconds = String(now.getSeconds()).padStart(2, "0");
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
private log(level: LogLevel, message: string, ...args: unknown[]): void {
|
||||
if (LOG_LEVELS[level] < this.minLevel) return;
|
||||
private log(level: LogLevel, message: string, ...args: unknown[]): void {
|
||||
if (LOG_LEVELS[level] < this.minLevel) return;
|
||||
|
||||
const timestamp = this.formatTimestamp();
|
||||
const color = COLORS[level];
|
||||
const levelStr = level.toUpperCase().padEnd(5);
|
||||
const prefix = this.prefix ? `[${this.prefix}] ` : "";
|
||||
const timestamp = this.formatTimestamp();
|
||||
const color = COLORS[level];
|
||||
const levelStr = level.toUpperCase().padEnd(5);
|
||||
const prefix = this.prefix ? `[${this.prefix}] ` : "";
|
||||
|
||||
const formattedArgs = args.map((arg) => {
|
||||
if (arg instanceof Error) {
|
||||
return arg;
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
const formattedArgs = args.map((arg) => {
|
||||
if (arg instanceof Error) {
|
||||
return arg;
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
|
||||
console.log(
|
||||
`${COLORS.gray}${timestamp}${COLORS.reset} ${color}${COLORS.bold}${levelStr}${COLORS.reset} ${prefix}${message}`,
|
||||
...formattedArgs,
|
||||
);
|
||||
}
|
||||
console.log(`${COLORS.gray}${timestamp}${COLORS.reset} ${color}${COLORS.bold}${levelStr}${COLORS.reset} ${prefix}${message}`, ...formattedArgs);
|
||||
}
|
||||
|
||||
debug(message: string, ...args: unknown[]): void {
|
||||
this.log("debug", message, ...args);
|
||||
}
|
||||
debug(message: string, ...args: unknown[]): void {
|
||||
this.log("debug", message, ...args);
|
||||
}
|
||||
|
||||
info(message: string, ...args: unknown[]): void {
|
||||
this.log("info", message, ...args);
|
||||
}
|
||||
info(message: string, ...args: unknown[]): void {
|
||||
this.log("info", message, ...args);
|
||||
}
|
||||
|
||||
warn(message: string, ...args: unknown[]): void {
|
||||
this.log("warn", message, ...args);
|
||||
}
|
||||
warn(message: string, ...args: unknown[]): void {
|
||||
this.log("warn", message, ...args);
|
||||
}
|
||||
|
||||
error(message: string, ...args: unknown[]): void {
|
||||
this.log("error", message, ...args);
|
||||
}
|
||||
error(message: string, ...args: unknown[]): void {
|
||||
this.log("error", message, ...args);
|
||||
}
|
||||
|
||||
fatal(message: string, ...args: unknown[]): never {
|
||||
this.log("error", message, ...args);
|
||||
process.exit(1);
|
||||
}
|
||||
fatal(message: string, ...args: unknown[]): never {
|
||||
this.log("error", message, ...args);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
child(prefix: string): Logger {
|
||||
const childPrefix = this.prefix ? `${this.prefix}:${prefix}` : prefix;
|
||||
return new Logger({ prefix: childPrefix, level: this.getLevel() });
|
||||
}
|
||||
child(prefix: string): Logger {
|
||||
const childPrefix = this.prefix ? `${this.prefix}:${prefix}` : prefix;
|
||||
return new Logger({ prefix: childPrefix, level: this.getLevel() });
|
||||
}
|
||||
|
||||
private getLevel(): LogLevel {
|
||||
const entry = Object.entries(LOG_LEVELS).find(
|
||||
([, value]) => value === this.minLevel,
|
||||
);
|
||||
return (entry?.[0] as LogLevel) || "info";
|
||||
}
|
||||
private getLevel(): LogLevel {
|
||||
const entry = Object.entries(LOG_LEVELS).find(([, value]) => value === this.minLevel);
|
||||
return (entry?.[0] as LogLevel) || "info";
|
||||
}
|
||||
}
|
||||
|
||||
export const createLogger = (options?: LoggerOptions): Logger => {
|
||||
return new Logger(options);
|
||||
return new Logger(options);
|
||||
};
|
||||
|
||||
export const logger = createLogger();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"removeComments": false
|
||||
},
|
||||
"tsc-alias": {
|
||||
"resolveFullPaths": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"removeComments": false
|
||||
},
|
||||
"tsc-alias": {
|
||||
"resolveFullPaths": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"types": ["node"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./src/*"],
|
||||
"~": ["./src/index"]
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"paths": {
|
||||
"~/*": ["./src/*"],
|
||||
"~": ["./src/index"]
|
||||
},
|
||||
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
},
|
||||
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user