Uecko_ERP/apps/server/src/config/config.ts
2026-02-12 15:46:47 +01:00

155 lines
3.3 KiB
TypeScript

import type { BaseConfigType } from "@erp/core/api";
import type { ILogger } from "@repo/rdx-logger";
import dotenv from "dotenv";
import { formatZodErrors } from "./env-error";
import { EnvSchema } from "./env-schema";
import { loadCompanyCertificates } from "./load-company-certificates";
import { logConfigSummary } from "./log-config";
dotenv.config();
let _config: ConfigType | null = null;
export type ConfigType = BaseConfigType & {
env: string;
server: {
port: number;
apiBasePath: string;
frontendUrl: string;
trustProxy: number;
timezone: string;
};
database: {
dialect: "mysql" | "postgres" | "sqlite" | "mariadb" | "mssql" | "db2" | "snowflake" | "oracle";
host: string;
port: number;
name: string;
user: string;
password: string;
logging: boolean;
ssl: boolean;
syncMode: string;
};
auth: {
jwt: {
secret: string;
accessExpiration: string;
refreshExpiration: string;
};
};
paths: {
templates: string;
documents: string;
signedDocuments: string;
fastReportBin: string;
};
signingService: {
url: string;
method: string;
timeoutMs: number;
maxRetries: number;
};
certificates?: Record<string, unknown>;
flags: {
isProd: boolean;
isDev: boolean;
isTest: boolean;
};
};
export const initConfig = (logger: ILogger): ConfigType => {
if (_config) {
return _config;
}
const parsed = EnvSchema.safeParse(process.env);
if (!parsed.success) {
const errors = formatZodErrors(parsed.error);
logger.error("Invalid environment configuration", {
errorCount: errors.length,
errors,
});
throw new Error("Invalid environment configuration");
}
const env = parsed.data;
const certificates = loadCompanyCertificates(env.COMPANY_CERTIFICATES_PATH, logger);
_config = {
env: env.NODE_ENV,
server: {
port: env.PORT,
apiBasePath: env.API_BASE_PATH,
frontendUrl: env.FRONTEND_URL,
trustProxy: env.TRUST_PROXY,
timezone: env.TIMEZONE,
},
database: {
dialect: env.DB_DIALECT,
host: env.DB_HOST,
port: env.DB_PORT,
name: env.DB_NAME,
user: env.DB_USER,
password: env.DB_PASS,
logging: env.DB_LOGGING,
ssl: env.DB_SSL,
syncMode: env.DB_SYNC_MODE,
},
auth: {
jwt: {
secret: env.JWT_SECRET,
accessExpiration: env.JWT_ACCESS_EXPIRATION,
refreshExpiration: env.JWT_REFRESH_EXPIRATION,
},
},
paths: {
templates: env.TEMPLATES_PATH,
documents: env.DOCUMENTS_PATH,
signedDocuments: env.SIGNED_DOCUMENTS_PATH,
fastReportBin: env.FASTREPORT_BIN,
},
signingService: {
url: env.SIGNING_SERVICE_URL,
method: env.SIGNING_SERVICE_METHOD,
timeoutMs: env.SIGNING_SERVICE_TIMEOUT_MS,
maxRetries: env.SIGNING_SERVICE_MAX_RETRIES,
},
certificates,
flags: {
isProd: env.NODE_ENV === "production",
isDev: env.NODE_ENV === "development",
isTest: env.NODE_ENV === "test",
},
};
logConfigSummary(_config, logger);
return _config;
};
export const Config = (): ConfigType => {
if (!_config) {
throw new Error("Config not initialized. Call initConfig(logger) during bootstrap.");
}
return _config;
};