UNPKG

@ajejoseph22/proxx

Version:

A lightweight HTTPS/HTTP proxy server with bandwidth tracking, basic auth and real-time analytics.

72 lines (59 loc) 1.84 kB
import fs from "fs/promises"; import path from "path"; import merge from "lodash.merge"; import { ProxyDBRecord, AuthDBRecord } from "../../types"; export interface DBSchema { auth: Record<string, AuthDBRecord>; metrics: Record<string, ProxyDBRecord>; } export interface IDatabaseService { initialize(): Promise<void>; save(data: Partial<DBSchema>): Promise<void>; getData(): DBSchema; } export class DatabaseError extends Error { constructor( message: string, public readonly cause?: Error, ) { super(message); this.name = "DatabaseError"; } } export class DatabaseService { private readonly dbPath: string; private data: DBSchema = { auth: {}, metrics: {} }; constructor() { this.dbPath = process.env.DB_PATH || path.join(__dirname, "db.json"); } async initialize(): Promise<void> { try { const dbFileExists = await fs .access(this.dbPath) .then(() => true) .catch(() => false); if (!dbFileExists) { console.log("Creating new DB file at ", this.dbPath); await fs.writeFile(this.dbPath, JSON.stringify(this.data, null, 2)); } const fileContent = await fs.readFile(this.dbPath, "utf-8"); if (!fileContent) await fs.writeFile(this.dbPath, JSON.stringify(this.data, null, 2)); else this.data = JSON.parse(fileContent); } catch (error) { throw new DatabaseError("Failed to initialize DB", error as Error); } } async save(data: Partial<DBSchema>): Promise<void> { try { const newData = merge({}, this.data, data); await fs.writeFile(this.dbPath, JSON.stringify(newData, null, 2)); this.data = newData; } catch (error) { throw new DatabaseError("Failed to save DB", error as Error); } } getData(): DBSchema { return { ...this.data }; } }