This repository has been archived on 2026-10-08. You can view files and clone it, but cannot push or open issues or pull requests.

168 lines
5.6 KiB
JavaScript

// config.js — environment-based JSON config + .env overrides (farmcontrol-api style)
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import dotenv from "dotenv";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Monorepo: repo-root .env then packages/server/.env (later files only fill missing keys)
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
dotenv.config({ path: path.resolve(__dirname, ".env") });
const CONFIG_PATH = path.resolve(__dirname, "config.json");
const NODE_ENV = process.env.NODE_ENV || "development";
function ensureShape(envConfig) {
if (!envConfig.server) envConfig.server = {};
if (!envConfig.app) envConfig.app = {};
if (!envConfig.database) envConfig.database = {};
if (!envConfig.database.mongo) envConfig.database.mongo = {};
if (!envConfig.auth) envConfig.auth = {};
if (!envConfig.auth.oidc) envConfig.auth.oidc = {};
if (!envConfig.device) envConfig.device = {};
if (!envConfig.mqtt) envConfig.mqtt = {};
if (!envConfig.s3) envConfig.s3 = {};
if (!envConfig.hub) envConfig.hub = {};
if (!Array.isArray(envConfig.patches)) envConfig.patches = [];
}
function loadConfig() {
try {
if (!fs.existsSync(CONFIG_PATH)) {
throw new Error(`Configuration file not found at ${CONFIG_PATH}`);
}
const configData = fs.readFileSync(CONFIG_PATH, "utf8");
const all = JSON.parse(configData);
if (!all[NODE_ENV]) {
throw new Error(
`Configuration for environment '${NODE_ENV}' not found in config.json`,
);
}
const envConfig = JSON.parse(JSON.stringify(all[NODE_ENV]));
ensureShape(envConfig);
if (process.env.PORT) {
envConfig.server.port = Number(process.env.PORT);
}
if (process.env.LOG_LEVEL) {
envConfig.server.logLevel = process.env.LOG_LEVEL;
}
if (process.env.CLIENT_URL) {
envConfig.app.urlClient = process.env.CLIENT_URL;
}
if (process.env.MONGODB_URI) {
envConfig.database.mongo.url = process.env.MONGODB_URI;
}
if (process.env.SESSION_SECRET) {
envConfig.auth.sessionSecret = process.env.SESSION_SECRET;
}
if (process.env.OIDC_ISSUER) {
envConfig.auth.oidc.issuer = process.env.OIDC_ISSUER;
}
if (process.env.OIDC_CLIENT_ID) {
envConfig.auth.oidc.clientId = process.env.OIDC_CLIENT_ID;
}
if (process.env.OIDC_CLIENT_SECRET) {
envConfig.auth.oidc.clientSecret = process.env.OIDC_CLIENT_SECRET;
}
if (process.env.OIDC_REDIRECT_URI) {
envConfig.auth.oidc.redirectUri = process.env.OIDC_REDIRECT_URI;
}
if (process.env.OIDC_APP_CALLBACK_URI) {
envConfig.auth.oidc.appCallbackUri = process.env.OIDC_APP_CALLBACK_URI;
}
if (process.env.APP_REDIRECT_URI) {
envConfig.auth.appRedirectUri = process.env.APP_REDIRECT_URI;
}
if (process.env.HUB_API_KEY) {
envConfig.hub.apiKey = process.env.HUB_API_KEY;
}
if (process.env.DEMO_TTN_APP_ID) {
envConfig.device.ttnApplicationId = process.env.DEMO_TTN_APP_ID;
}
if (process.env.DEMO_TTN_DEV_ID) {
envConfig.device.ttnDeviceId = process.env.DEMO_TTN_DEV_ID;
}
if (process.env.DEVICE_TTN_APPLICATION_ID) {
envConfig.device.ttnApplicationId = process.env.DEVICE_TTN_APPLICATION_ID;
}
if (process.env.DEVICE_TTN_DEVICE_ID) {
envConfig.device.ttnDeviceId = process.env.DEVICE_TTN_DEVICE_ID;
}
if (process.env.DEVICE_NAME) {
envConfig.device.name = process.env.DEVICE_NAME;
}
if (process.env.MQTT_CONFIG_PATH) {
envConfig.mqtt.configPath = process.env.MQTT_CONFIG_PATH;
}
if (process.env.S3_BUCKET) {
envConfig.s3.bucket = process.env.S3_BUCKET;
}
if (process.env.AWS_REGION) {
envConfig.s3.region = process.env.AWS_REGION;
}
if (process.env.S3_PREFIX) {
envConfig.s3.prefix = process.env.S3_PREFIX;
}
if (process.env.S3_ENDPOINT) {
envConfig.s3.endpoint = process.env.S3_ENDPOINT;
}
if (process.env.S3_FORCE_PATH_STYLE != null) {
const v = String(process.env.S3_FORCE_PATH_STYLE).toLowerCase();
envConfig.s3.forcePathStyle =
v === "1" || v === "true" || v === "yes";
}
if (process.env.S3_ACCESS_KEY_ID) {
envConfig.s3.accessKeyId = process.env.S3_ACCESS_KEY_ID;
} else if (process.env.AWS_ACCESS_KEY_ID) {
envConfig.s3.accessKeyId = process.env.AWS_ACCESS_KEY_ID;
}
if (process.env.S3_SECRET_ACCESS_KEY) {
envConfig.s3.secretAccessKey = process.env.S3_SECRET_ACCESS_KEY;
} else if (process.env.AWS_SECRET_ACCESS_KEY) {
envConfig.s3.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
}
if (process.env.S3_SESSION_TOKEN) {
envConfig.s3.sessionToken = process.env.S3_SESSION_TOKEN;
} else if (process.env.AWS_SESSION_TOKEN) {
envConfig.s3.sessionToken = process.env.AWS_SESSION_TOKEN;
}
if (!envConfig.auth.sessionSecret) {
throw new Error(
"SESSION_SECRET environment variable is required, or set auth.sessionSecret in config.json for this environment.",
);
}
if (NODE_ENV === "production") {
if (!envConfig.database.mongo.url?.trim()) {
throw new Error(
"database.mongo.url must be set for production (config.json or MONGODB_URI).",
);
}
if (!envConfig.app.urlClient?.trim()) {
throw new Error(
"app.urlClient must be set for production (config.json or CLIENT_URL).",
);
}
}
return envConfig;
} catch (err) {
console.error("Error loading config:", err);
throw err;
}
}
export function getEnvironment() {
return NODE_ENV;
}
const config = loadConfig();
export default config;