From 9e270bebe4c39966371f75dd050d8c6aaa1e6443 Mon Sep 17 00:00:00 2001 From: SantiagoRR2004 <114857078+SantiagoRR2004@users.noreply.github.com> Date: Tue, 17 Mar 2026 23:04:07 +0100 Subject: [PATCH] Fix #11744; Importing mysql2 and pg when it is not required (#11747) --- lib/database.ts | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/database.ts b/lib/database.ts index 86027214b4..13ccb5ba61 100644 --- a/lib/database.ts +++ b/lib/database.ts @@ -6,14 +6,31 @@ * @author Zarel */ -import * as mysql from 'mysql2'; -import * as pg from 'pg'; +import type * as mysql from 'mysql2'; +import type * as pg from 'pg'; export type BasicSQLValue = string | number | null; export type SQLRow = { [k: string]: BasicSQLValue }; export type SQLValue = BasicSQLValue | SQLStatement | SQLStatement[] | PartialOrSQL | BasicSQLValue[] | undefined; +let mysqlRuntime: typeof import('mysql2'); +let pgRuntime: typeof import('pg'); + +// Lazy-load mysql2 +try { + mysqlRuntime = require('mysql2'); +} catch { + // Only throw if someone tries to use MySQL +} + +// Lazy-load pg +try { + pgRuntime = require('pg'); +} catch { + // Only throw if someone tries to use Postgres +} + export function isSQL(value: any): value is SQLStatement { /** * This addresses a scenario where objects get out of sync due to hotpatching. @@ -333,12 +350,13 @@ export class DatabaseTable { export class MySQLDatabase extends Database { override type = 'mysql' as const; constructor(config: mysql.PoolOptions & { prefix?: string }) { + if (!mysqlRuntime) throw new Error(`Install the 'mysql2' module to use a MySQL database`); const prefix = config.prefix || ""; if (config.prefix) { config = { ...config }; delete config.prefix; } - super(mysql.createPool(config), prefix); + super(mysqlRuntime.createPool(config), prefix); } override _resolveSQL(query: SQLStatement): [query: string, values: BasicSQLValue[]] { let sql = query.sql[0]; @@ -375,14 +393,16 @@ export class MySQLDatabase extends Database { return this._query(sql, values); } override escapeId(id: string) { - return mysql.escapeId(id); + if (!mysqlRuntime) throw new Error(`Install the 'mysql2' module to use a MySQL database`); + return mysqlRuntime.escapeId(id); } } export class PGDatabase extends Database { override type = 'pg' as const; constructor(config: pg.PoolConfig) { - super(config ? new pg.Pool(config) : null!); + if (!pgRuntime) throw new Error(`Install the 'pg' module to use a Postgres database`); + super(config ? new pgRuntime.Pool(config) : null!); } override _resolveSQL(query: SQLStatement): [query: string, values: BasicSQLValue[]] { let sql = query.sql[0]; @@ -407,7 +427,8 @@ export class PGDatabase extends Database(query, values).then(res => ({ affectedRows: res.rowCount })); } override escapeId(id: string) { + if (!pgRuntime) throw new Error(`Install the 'pg' module to use a Postgres database`); // @ts-expect-error @types/pg really needs to be updated - return pg.escapeIdentifier(id); + return pgRuntime.escapeIdentifier(id); } }