refactor(db): move to core package (#4589)

This commit is contained in:
Meier Lukas
2025-12-17 08:59:52 +01:00
committed by GitHub
parent e954ea861c
commit 298a96054e
30 changed files with 258 additions and 217 deletions

View File

@@ -1,6 +1,6 @@
// Importing env files here to validate on build
import "@homarr/auth/env";
import "@homarr/db/env";
import "@homarr/core/infrastructure/db/env";
import "@homarr/common/env";
import "@homarr/core/infrastructure/logs/env";
import "@homarr/docker/env";

View File

@@ -5,6 +5,7 @@ import Database from "better-sqlite3";
import { BetterSQLite3Database, drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { DB_CASING } from "../../packages/core/src/infrastructure/db/constants";
import * as sqliteSchema from "../../packages/db/schema/sqlite";
export const createSqliteDbFileAsync = async () => {
@@ -16,7 +17,7 @@ export const createSqliteDbFileAsync = async () => {
const connection = new Database(localDbUrl);
const db = drizzle(connection, {
schema: sqliteSchema,
casing: "snake_case",
casing: DB_CASING,
});
await migrate(db, {

View File

@@ -10,7 +10,10 @@
"./infrastructure/logs": "./src/infrastructure/logs/index.ts",
"./infrastructure/logs/constants": "./src/infrastructure/logs/constants.ts",
"./infrastructure/logs/env": "./src/infrastructure/logs/env.ts",
"./infrastructure/logs/error": "./src/infrastructure/logs/error.ts"
"./infrastructure/logs/error": "./src/infrastructure/logs/error.ts",
"./infrastructure/db": "./src/infrastructure/db/index.ts",
"./infrastructure/db/env": "./src/infrastructure/db/env.ts",
"./infrastructure/db/constants": "./src/infrastructure/db/constants.ts"
},
"typesVersions": {
"*": {
@@ -28,7 +31,11 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"better-sqlite3": "^12.5.0",
"drizzle-orm": "^0.45.1",
"ioredis": "5.8.2",
"mysql2": "3.15.3",
"pg": "^8.16.3",
"superjson": "2.2.6",
"winston": "3.19.0",
"zod": "^4.1.13"
@@ -37,6 +44,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/better-sqlite3": "7.6.13",
"@types/pg": "^8.16.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}

View File

@@ -0,0 +1,3 @@
import type { Casing } from "drizzle-orm";
export const DB_CASING: Casing = "snake_case";

View File

@@ -0,0 +1,27 @@
import { DB_CASING } from "../constants";
import { createDbMapping } from "../mapping";
import { createMysqlDb } from "./mysql";
import { createPostgresDb } from "./postgresql";
import type { SharedDrizzleConfig } from "./shared";
import { WinstonDrizzleLogger } from "./shared";
import { createSqliteDb } from "./sqlite";
export type Database<TSchema extends Record<string, unknown>> = ReturnType<typeof createSqliteDb<TSchema>>;
export const createSharedConfig = <TSchema extends Record<string, unknown>>(
schema: TSchema,
): SharedDrizzleConfig<TSchema> => ({
logger: new WinstonDrizzleLogger(),
casing: DB_CASING,
schema,
});
export const createDb = <TSchema extends Record<string, unknown>>(schema: TSchema) => {
const config = createSharedConfig(schema);
return createDbMapping({
mysql2: () => createMysqlDb(config),
"node-postgres": () => createPostgresDb(config),
"better-sqlite3": () => createSqliteDb(config),
});
};

View File

@@ -0,0 +1,33 @@
import { drizzle } from "drizzle-orm/mysql2";
import mysql from "mysql2";
import type { PoolOptions } from "mysql2";
import { dbEnv } from "../env";
import type { SharedDrizzleConfig } from "./shared";
export const createMysqlDb = <TSchema extends Record<string, unknown>>(config: SharedDrizzleConfig<TSchema>) => {
const connection = createMysqlDbConnection();
return drizzle<TSchema>(connection, {
...config,
mode: "default",
});
};
const createMysqlDbConnection = () => {
const defaultOptions = {
maxIdle: 0,
idleTimeout: 60000,
enableKeepAlive: true,
} satisfies Partial<PoolOptions>;
if (!dbEnv.HOST) {
return mysql.createPool({ ...defaultOptions, uri: dbEnv.URL });
}
return mysql.createPool({
...defaultOptions,
port: dbEnv.PORT,
user: dbEnv.USER,
password: dbEnv.PASSWORD,
});
};

View File

@@ -0,0 +1,38 @@
import { drizzle as drizzlePostgres } from "drizzle-orm/node-postgres";
import type { PoolOptions as PostgresPoolOptions } from "pg";
import { Pool as PostgresPool } from "pg";
import { dbEnv } from "../env";
import type { SharedDrizzleConfig } from "./shared";
export const createPostgresDb = <TSchema extends Record<string, unknown>>(config: SharedDrizzleConfig<TSchema>) => {
const connection = createPostgresDbConnection();
return drizzlePostgres({
...config,
client: connection,
});
};
const createPostgresDbConnection = () => {
const defaultOptions = {
max: 0,
idleTimeoutMillis: 60000,
allowExitOnIdle: false,
} satisfies Partial<PostgresPoolOptions>;
if (!dbEnv.HOST) {
return new PostgresPool({
...defaultOptions,
connectionString: dbEnv.URL,
});
}
return new PostgresPool({
...defaultOptions,
host: dbEnv.HOST,
port: dbEnv.PORT,
database: dbEnv.NAME,
user: dbEnv.USER,
password: dbEnv.PASSWORD,
});
};

View File

@@ -0,0 +1,15 @@
import type { DrizzleConfig, Logger } from "drizzle-orm";
import { createLogger } from "../../logs";
export type SharedDrizzleConfig<TSchema extends Record<string, unknown>> = Required<
Pick<DrizzleConfig<TSchema>, "logger" | "casing" | "schema">
>;
const logger = createLogger({ module: "db" });
export class WinstonDrizzleLogger implements Logger {
logQuery(query: string, _: unknown[]): void {
logger.debug("Executed SQL query", { query });
}
}

View File

@@ -0,0 +1,10 @@
import Database from "better-sqlite3";
import { drizzle as drizzleSqlite } from "drizzle-orm/better-sqlite3";
import { dbEnv } from "../env";
import type { SharedDrizzleConfig } from "./shared";
export const createSqliteDb = <TSchema extends Record<string, unknown>>(config: SharedDrizzleConfig<TSchema>) => {
const connection = new Database(dbEnv.URL);
return drizzleSqlite<TSchema>(connection, config);
};

View File

@@ -1,7 +1,6 @@
import { z } from "zod/v4";
import { env as commonEnv } from "@homarr/common/env";
import { createEnv } from "@homarr/core/infrastructure/env";
import { createEnv, runtimeEnvWithPrefix } from "@homarr/core/infrastructure/env";
const drivers = {
betterSqlite3: "better-sqlite3",
@@ -15,40 +14,40 @@ const onlyAllowUrl = isDriver(drivers.betterSqlite3);
const urlRequired = onlyAllowUrl || !isUsingDbHost;
const hostRequired = isUsingDbHost && !onlyAllowUrl;
export const env = createEnv({
export const dbEnv = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app isn't
* built with invalid env vars.
*/
server: {
DB_DRIVER: z
DRIVER: z
.union([z.literal(drivers.betterSqlite3), z.literal(drivers.mysql2), z.literal(drivers.nodePostgres)], {
message: `Invalid database driver, supported are ${Object.keys(drivers).join(", ")}`,
})
.default(drivers.betterSqlite3),
...(urlRequired
? {
DB_URL:
URL:
// Fallback to the default sqlite file path in production
commonEnv.NODE_ENV === "production" && isDriver("better-sqlite3")
process.env.NODE_ENV === "production" && isDriver("better-sqlite3")
? z.string().default("/appdata/db/db.sqlite")
: z.string().nonempty(),
}
: {}),
...(hostRequired
? {
DB_HOST: z.string(),
DB_PORT: z
HOST: z.string(),
PORT: z
.string()
.regex(/\d+/)
.transform(Number)
.refine((number) => number >= 1)
.default(isDriver(drivers.mysql2) ? 3306 : 5432),
DB_USER: z.string(),
DB_PASSWORD: z.string(),
DB_NAME: z.string(),
USER: z.string(),
PASSWORD: z.string(),
NAME: z.string(),
}
: {}),
},
experimental__runtimeEnv: process.env,
runtimeEnv: runtimeEnvWithPrefix("DB_"),
});

View File

@@ -0,0 +1,9 @@
import { createDbMapping } from "./mapping";
export { createDb } from "./drivers";
export const createSchema = createDbMapping;
export { createMysqlDb } from "./drivers/mysql";
export { createSqliteDb } from "./drivers/sqlite";
export { createPostgresDb } from "./drivers/postgresql";
export { createSharedConfig as createSharedDbConfig } from "./drivers";

View File

@@ -0,0 +1,9 @@
import { dbEnv } from "./env";
type DbMappingInput = Record<typeof dbEnv.DRIVER, () => unknown>;
export const createDbMapping = <TInput extends DbMappingInput>(input: TInput) => {
// The DRIVER can be undefined when validation of env vars is skipped
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return input[dbEnv.DRIVER ?? "better-sqlite3"]() as ReturnType<TInput["better-sqlite3"]>;
};

View File

@@ -1,9 +1,9 @@
import type { InferInsertModel } from "drizzle-orm";
import { objectEntries } from "@homarr/common";
import { dbEnv } from "@homarr/core/infrastructure/db/env";
import type { HomarrDatabase, HomarrDatabaseMysql, HomarrDatabasePostgresql } from "./driver";
import { env } from "./env";
import * as schema from "./schema";
type TableKey = {
@@ -11,11 +11,11 @@ type TableKey = {
}[keyof typeof schema];
export function isMysql(): boolean {
return env.DB_DRIVER === "mysql2";
return dbEnv.DRIVER === "mysql2";
}
export function isPostgresql(): boolean {
return env.DB_DRIVER === "node-postgres";
return dbEnv.DRIVER === "node-postgres";
}
export const createDbInsertCollectionForTransaction = <TTableKey extends TableKey>(
@@ -66,7 +66,7 @@ export const createDbInsertCollectionWithoutTransaction = <TTableKey extends Tab
return {
...collection,
insertAllAsync: async (db: HomarrDatabase) => {
switch (env.DB_DRIVER) {
switch (dbEnv.DRIVER) {
case "mysql2":
case "node-postgres":
// For mysql2 and node-postgres, we can use the async insertAllAsync method

View File

@@ -1,19 +1,20 @@
import type { Config } from "drizzle-kit";
import { env } from "../env";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import { dbEnv } from "@homarr/core/infrastructure/db/env";
export default {
dialect: "mysql",
schema: "./schema",
casing: "snake_case",
dbCredentials: env.DB_URL
? { url: env.DB_URL }
casing: DB_CASING,
dbCredentials: dbEnv.URL
? { url: dbEnv.URL }
: {
host: env.DB_HOST,
user: env.DB_USER,
password: env.DB_PASSWORD,
database: env.DB_NAME,
port: env.DB_PORT,
host: dbEnv.HOST,
port: dbEnv.PORT,
database: dbEnv.NAME,
user: dbEnv.USER,
password: dbEnv.PASSWORD,
},
out: "./migrations/mysql",
} satisfies Config;

View File

@@ -1,20 +1,21 @@
import type { Config } from "drizzle-kit";
import { env } from "../env";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import { dbEnv } from "@homarr/core/infrastructure/db/env";
export default {
dialect: "postgresql",
schema: "./schema",
casing: "snake_case",
casing: DB_CASING,
dbCredentials: env.DB_URL
? { url: env.DB_URL }
dbCredentials: dbEnv.URL
? { url: dbEnv.URL }
: {
host: env.DB_HOST,
port: env.DB_PORT,
user: env.DB_USER,
password: env.DB_PASSWORD,
database: env.DB_NAME,
host: dbEnv.HOST,
port: dbEnv.PORT,
database: dbEnv.NAME,
user: dbEnv.USER,
password: dbEnv.PASSWORD,
},
out: "./migrations/postgresql",
} satisfies Config;

View File

@@ -1,11 +1,12 @@
import type { Config } from "drizzle-kit";
import { env } from "../env";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import { dbEnv } from "@homarr/core/infrastructure/db/env";
export default {
dialect: "sqlite",
schema: "./schema",
casing: "snake_case",
dbCredentials: { url: env.DB_URL },
casing: DB_CASING,
dbCredentials: { url: dbEnv.URL },
out: "./migrations/sqlite",
} satisfies Config;

View File

@@ -1,115 +1,11 @@
import type { Database as BetterSqlite3Connection } from "better-sqlite3";
import Database from "better-sqlite3";
import type { Logger } from "drizzle-orm";
import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
import { drizzle as drizzleSqlite } from "drizzle-orm/better-sqlite3";
import type { MySql2Database } from "drizzle-orm/mysql2";
import { drizzle as drizzleMysql } from "drizzle-orm/mysql2";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import { drizzle as drizzlePg } from "drizzle-orm/node-postgres";
import type { Pool as MysqlConnectionPool } from "mysql2";
import mysql from "mysql2";
import { Pool as PostgresPool } from "pg";
import { createLogger } from "@homarr/core/infrastructure/logs";
import { env } from "./env";
import * as mysqlSchema from "./schema/mysql";
import * as pgSchema from "./schema/postgresql";
import * as sqliteSchema from "./schema/sqlite";
const logger = createLogger({ module: "db" });
import type * as mysqlSchema from "./schema/mysql";
import type * as pgSchema from "./schema/postgresql";
import type * as sqliteSchema from "./schema/sqlite";
export type HomarrDatabase = BetterSQLite3Database<typeof sqliteSchema>;
export type HomarrDatabaseMysql = MySql2Database<typeof mysqlSchema>;
export type HomarrDatabasePostgresql = NodePgDatabase<typeof pgSchema>;
const init = () => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!connection) {
switch (env.DB_DRIVER) {
case "mysql2":
initMySQL2();
break;
case "node-postgres":
initNodePostgres();
break;
default:
initBetterSqlite();
break;
}
}
};
export let connection: BetterSqlite3Connection | MysqlConnectionPool | PostgresPool;
export let database: HomarrDatabase;
class WinstonDrizzleLogger implements Logger {
logQuery(query: string, _: unknown[]): void {
logger.debug("Executed SQL query", { query });
}
}
const initBetterSqlite = () => {
connection = new Database(env.DB_URL);
database = drizzleSqlite(connection, {
schema: sqliteSchema,
logger: new WinstonDrizzleLogger(),
casing: "snake_case",
}) as unknown as never;
};
const initMySQL2 = () => {
if (!env.DB_HOST) {
connection = mysql.createPool({ uri: env.DB_URL, maxIdle: 0, idleTimeout: 60000, enableKeepAlive: true });
} else {
connection = mysql.createPool({
host: env.DB_HOST,
database: env.DB_NAME,
port: env.DB_PORT,
user: env.DB_USER,
password: env.DB_PASSWORD,
maxIdle: 0,
idleTimeout: 60000,
enableKeepAlive: true,
});
}
database = drizzleMysql(connection, {
schema: mysqlSchema,
mode: "default",
logger: new WinstonDrizzleLogger(),
casing: "snake_case",
}) as unknown as HomarrDatabase;
};
const initNodePostgres = () => {
if (!env.DB_HOST) {
connection = new PostgresPool({
connectionString: env.DB_URL,
max: 0,
idleTimeoutMillis: 60000,
allowExitOnIdle: false,
});
} else {
connection = new PostgresPool({
host: env.DB_HOST,
database: env.DB_NAME,
port: env.DB_PORT,
user: env.DB_USER,
password: env.DB_PASSWORD,
max: 0,
idleTimeoutMillis: 60000,
allowExitOnIdle: false,
});
}
database = drizzlePg({
logger: new WinstonDrizzleLogger(),
schema: pgSchema,
casing: "snake_case",
client: connection,
}) as unknown as HomarrDatabase;
};
init();

View File

@@ -1,12 +1,12 @@
import Database from "better-sqlite3";
import { createDb } from "@homarr/core/infrastructure/db";
import { database } from "./driver";
import { schema } from "./schema";
export * from "drizzle-orm";
export const db = database;
export type Database = typeof db;
export type { HomarrDatabaseMysql, HomarrDatabasePostgresql } from "./driver";
export const db = createDb(schema);
export type Database = typeof db;
export { handleDiffrentDbDriverOperationsAsync as handleTransactionsAsync } from "./transactions";

View File

@@ -1,7 +1,7 @@
import { applyCustomMigrationsAsync } from ".";
import { database } from "../../driver";
import { db } from "../..";
applyCustomMigrationsAsync(database)
applyCustomMigrationsAsync(db)
.then(() => {
console.log("Custom migrations applied successfully");
process.exit(0);

View File

@@ -1,9 +1,8 @@
import { drizzle } from "drizzle-orm/mysql2";
import { migrate } from "drizzle-orm/mysql2/migrator";
import mysql from "mysql2";
import { createMysqlDb, createSharedDbConfig } from "@homarr/core/infrastructure/db";
import type { Database } from "../..";
import { env } from "../../env";
import * as mysqlSchema from "../../schema/mysql";
import { applyCustomMigrationsAsync } from "../custom";
import { seedDataAsync } from "../seed";
@@ -11,23 +10,8 @@ import { seedDataAsync } from "../seed";
const migrationsFolder = process.argv[2] ?? ".";
const migrateAsync = async () => {
const mysql2 = mysql.createConnection(
env.DB_URL
? { uri: env.DB_URL }
: {
host: env.DB_HOST,
database: env.DB_NAME,
port: env.DB_PORT,
user: env.DB_USER,
password: env.DB_PASSWORD,
},
);
const db = drizzle(mysql2, {
mode: "default",
schema: mysqlSchema,
casing: "snake_case",
});
const config = createSharedDbConfig(mysqlSchema);
const db = createMysqlDb(config);
await migrate(db, { migrationsFolder });
await seedDataAsync(db as unknown as Database);

View File

@@ -1,9 +1,8 @@
import { drizzle } from "drizzle-orm/node-postgres";
import { migrate } from "drizzle-orm/node-postgres/migrator";
import { Pool } from "pg";
import { createPostgresDb, createSharedDbConfig } from "@homarr/core/infrastructure/db";
import type { Database } from "../..";
import { env } from "../../env";
import * as pgSchema from "../../schema/postgresql";
import { applyCustomMigrationsAsync } from "../custom";
import { seedDataAsync } from "../seed";
@@ -11,23 +10,8 @@ import { seedDataAsync } from "../seed";
const migrationsFolder = process.argv[2] ?? ".";
const migrateAsync = async () => {
const pool = new Pool(
env.DB_URL
? { connectionString: env.DB_URL }
: {
host: env.DB_HOST,
database: env.DB_NAME,
port: env.DB_PORT,
user: env.DB_USER,
password: env.DB_PASSWORD,
},
);
const db = drizzle({
schema: pgSchema,
casing: "snake_case",
client: pool,
});
const config = createSharedDbConfig(pgSchema);
const db = createPostgresDb(config);
await migrate(db, { migrationsFolder });
await seedDataAsync(db as unknown as Database);

View File

@@ -1,7 +1,7 @@
import { database } from "../driver";
import { db } from "..";
import { seedDataAsync } from "./seed";
seedDataAsync(database)
seedDataAsync(db)
.then(() => {
console.log("Seed complete");
process.exit(0);

View File

@@ -1,8 +1,7 @@
import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { env } from "../../env";
import { createSharedDbConfig, createSqliteDb } from "@homarr/core/infrastructure/db";
import * as sqliteSchema from "../../schema/sqlite";
import { applyCustomMigrationsAsync } from "../custom";
import { seedDataAsync } from "../seed";
@@ -10,9 +9,8 @@ import { seedDataAsync } from "../seed";
const migrationsFolder = process.argv[2] ?? ".";
const migrateAsync = async () => {
const sqlite = new Database(env.DB_URL.replace("file:", ""));
const db = drizzle(sqlite, { schema: sqliteSchema, casing: "snake_case" });
const config = createSharedDbConfig(sqliteSchema);
const db = createSqliteDb(config);
migrate(db, { migrationsFolder });

View File

@@ -10,8 +10,7 @@
"./schema": "./schema/index.ts",
"./test": "./test/index.ts",
"./queries": "./queries/index.ts",
"./validationSchemas": "./validationSchemas.ts",
"./env": "./env.ts"
"./validationSchemas": "./validationSchemas.ts"
},
"main": "./index.ts",
"types": "./index.ts",

View File

@@ -1,20 +1,19 @@
import type { InferSelectModel } from "drizzle-orm";
import { env } from "../env";
import { createSchema } from "@homarr/core/infrastructure/db";
import * as mysqlSchema from "./mysql";
import * as pgSchema from "./postgresql";
import * as sqliteSchema from "./sqlite";
export type PostgreSqlSchema = typeof pgSchema;
export type MySqlSchema = typeof mysqlSchema;
type Schema = typeof sqliteSchema;
const schema =
env.DB_DRIVER === "mysql2"
? (mysqlSchema as unknown as Schema)
: env.DB_DRIVER === "node-postgres"
? (pgSchema as unknown as Schema)
: sqliteSchema;
export const schema = createSchema({
"better-sqlite3": () => sqliteSchema,
mysql2: () => mysqlSchema,
"node-postgres": () => pgSchema,
});
// Sadly we can't use export * from here as we have multiple possible exports
export const {

View File

@@ -2,11 +2,13 @@ import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import * as sqliteSchema from "../schema/sqlite";
export const createDb = (debug?: boolean) => {
const sqlite = new Database(":memory:");
const db = drizzle(sqlite, { schema: sqliteSchema, logger: debug, casing: "snake_case" });
const db = drizzle(sqlite, { schema: sqliteSchema, logger: debug, casing: DB_CASING });
migrate(db, {
migrationsFolder: "./packages/db/migrations/sqlite",
});

View File

@@ -5,6 +5,8 @@ import { migrate } from "drizzle-orm/mysql2/migrator";
import mysql from "mysql2";
import { describe, test } from "vitest";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import * as mysqlSchema from "../schema/mysql";
describe("Mysql Migration", () => {
@@ -22,7 +24,7 @@ describe("Mysql Migration", () => {
const database = drizzle(connection, {
schema: mysqlSchema,
mode: "default",
casing: "snake_case",
casing: DB_CASING,
});
// Run migrations and check if it works

View File

@@ -5,6 +5,8 @@ import { migrate } from "drizzle-orm/node-postgres/migrator";
import { Pool } from "pg";
import { describe, test } from "vitest";
import { DB_CASING } from "@homarr/core/infrastructure/db/constants";
import * as pgSchema from "../schema/postgresql";
describe("PostgreSql Migration", () => {
@@ -26,7 +28,7 @@ describe("PostgreSql Migration", () => {
const database = drizzle({
schema: pgSchema,
casing: "snake_case",
casing: DB_CASING,
client: pool,
});

18
pnpm-lock.yaml generated
View File

@@ -920,9 +920,21 @@ importers:
'@t3-oss/env-nextjs':
specifier: ^0.13.8
version: 0.13.8(arktype@2.1.20)(typescript@5.9.3)(zod@4.1.13)
better-sqlite3:
specifier: ^12.5.0
version: 12.5.0
drizzle-orm:
specifier: ^0.45.1
version: 0.45.1(@libsql/client-wasm@0.14.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(better-sqlite3@12.5.0)(gel@2.0.0)(mysql2@3.15.3)(pg@8.16.3)
ioredis:
specifier: 5.8.2
version: 5.8.2
mysql2:
specifier: 3.15.3
version: 3.15.3
pg:
specifier: ^8.16.3
version: 8.16.3
superjson:
specifier: 2.2.6
version: 2.2.6
@@ -942,6 +954,12 @@ importers:
'@homarr/tsconfig':
specifier: workspace:^0.1.0
version: link:../../tooling/typescript
'@types/better-sqlite3':
specifier: 7.6.13
version: 7.6.13
'@types/pg':
specifier: ^8.16.0
version: 8.16.0
eslint:
specifier: ^9.39.1
version: 9.39.1

View File

@@ -10,7 +10,8 @@ if [ "$DB_MIGRATIONS_DISABLED" = "true" ]; then
echo "DB migrations are disabled, skipping"
else
echo "Running DB migrations"
node ./db/migrations/$DB_DIALECT/migrate.cjs ./db/migrations/$DB_DIALECT
# We disable redis logs during migration as the redis client is not yet started
DISABLE_REDIS_LOGS=true node ./db/migrations/$DB_DIALECT/migrate.cjs ./db/migrations/$DB_DIALECT
fi
# Auth secret is generated every time the container starts as it is required, but not used because we don't need JWTs or Mail hashing