diff --git a/drizzle.config.ts b/drizzle.config.ts index 2cb423e6..a0df5c5f 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,5 +1,6 @@ import { defineConfig } from "drizzle-kit"; -import environment from "@server/environment" +import environment from "@server/environment"; +import path from "path"; export default defineConfig({ dialect: "sqlite", @@ -7,6 +8,6 @@ export default defineConfig({ out: "server/migrations", verbose: true, dbCredentials: { - url: `${environment.CONFIG_PATH}/db/db.sqlite` + url: path.join(environment.CONFIG_PATH, "db", "db.sqlite"), }, }); diff --git a/server/db/index.ts b/server/db/index.ts index b8094cac..206a4d24 100644 --- a/server/db/index.ts +++ b/server/db/index.ts @@ -2,8 +2,11 @@ import { drizzle } from "drizzle-orm/better-sqlite3"; import Database from "better-sqlite3"; import * as schema from "@server/db/schema"; import environment from "@server/environment"; +import path from "path"; -const sqlite = new Database(`${environment.CONFIG_PATH}/db/db.sqlite`); +const sqlite = new Database( + path.join(environment.CONFIG_PATH, "db", "db.sqlite"), +); export const db = drizzle(sqlite, { schema }); export default db; diff --git a/server/environment.ts b/server/environment.ts index 43767afe..78de1e76 100644 --- a/server/environment.ts +++ b/server/environment.ts @@ -1,13 +1,26 @@ import { z } from "zod"; import { fromError } from "zod-validation-error"; +import path from "path"; const environmentSchema = z.object({ - ENVIRONMENT: z.string(), - LOG_LEVEL: z.string(), + ENVIRONMENT: z.enum(["dev", "prod"]), + LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]), SAVE_LOGS: z.string().transform((val) => val === "true"), - PORT: z.string(), - INTERNAL_PORT: z.string(), - CONFIG_PATH: z.string(), + EXTERNAL_PORT: z + .string() + .transform((val) => parseInt(val, 10)) + .pipe(z.number()), + INTERNAL_PORT: z + .string() + .transform((val) => parseInt(val, 10)) + .pipe(z.number()), + CONFIG_PATH: z.string().transform((val) => { + // validate the path and remove any trailing slashes + const resolvedPath = path.resolve(val); + return resolvedPath.endsWith(path.sep) + ? resolvedPath.slice(0, -1) + : resolvedPath; + }), API_VERSION: z.string(), }); @@ -15,9 +28,10 @@ const environment = { ENVIRONMENT: (process.env.ENVIRONMENT as string) || "dev", LOG_LEVEL: (process.env.LOG_LEVEL as string) || "debug", SAVE_LOGS: (process.env.SAVE_LOGS as string) || "false", - PORT: (process.env.PORT as string) || "3000", + EXTERNAL_PORT: (process.env.EXTERNAL_PORT as string) || "3000", INTERNAL_PORT: (process.env.INTERNAL_PORT as string) || "3001", - CONFIG_PATH: process.env.CONFIG_PATH as string, + CONFIG_PATH: + (process.env.CONFIG_PATH as string) || path.join(__dirname, "config"), API_VERSION: (process.env.API_VERSION as string) || "v1", }; diff --git a/server/index.ts b/server/index.ts index 0f96f033..5ef2ba3f 100644 --- a/server/index.ts +++ b/server/index.ts @@ -11,7 +11,7 @@ import external from "@server/routers/external"; const dev = environment.ENVIRONMENT !== "prod"; const app = next({ dev }); const handle = app.getRequestHandler(); -const mainPort = environment.PORT; +const mainPort = environment.EXTERNAL_PORT; const internalPort = environment.INTERNAL_PORT; app.prepare().then(() => { diff --git a/server/logger.ts b/server/logger.ts index 60b4a7ae..9969530b 100644 --- a/server/logger.ts +++ b/server/logger.ts @@ -1,7 +1,7 @@ import "winston-daily-rotate-file"; - import environment from "@server/environment"; import * as winston from "winston"; +import path from "path"; const hformat = winston.format.printf( ({ level, label, message, timestamp, ...metadata }) => { @@ -27,7 +27,11 @@ const transports: any = [ if (environment.SAVE_LOGS) { transports.push( new winston.transports.DailyRotateFile({ - filename: `${environment.CONFIG_PATH}/logs/pangolin-%DATE%.log`, + filename: path.join( + environment.CONFIG_PATH, + "logs", + "pangolin-%DATE%.log", + ), datePattern: "YYYY-MM-DD", zippedArchive: true, maxSize: "20m", @@ -38,7 +42,11 @@ if (environment.SAVE_LOGS) { ); transports.push( new winston.transports.DailyRotateFile({ - filename: `${environment.CONFIG_PATH}/logs/.machinelogs-%DATE%.json`, + filename: path.join( + environment.CONFIG_PATH, + "logs", + ".machinelogs-%DATE%.json", + ), datePattern: "YYYY-MM-DD", zippedArchive: true, maxSize: "20m", @@ -46,7 +54,7 @@ if (environment.SAVE_LOGS) { createSymlink: true, symlinkName: ".machinelogs.json", format: winston.format.combine( - winston.format.timestamp(), + winston.format.timestamp(), winston.format.splat(), winston.format.json(), ),