2021-08-02 08:21:48 +00:00
|
|
|
import * as Joi from 'joi';
|
2022-09-16 15:20:44 +00:00
|
|
|
import * as path from 'path';
|
2022-12-22 20:39:57 +00:00
|
|
|
import * as fs from 'fs';
|
|
|
|
|
import * as dotenv from 'dotenv';
|
|
|
|
|
import { isEmpty } from 'lodash';
|
|
|
|
|
const url = require('url');
|
|
|
|
|
const querystring = require('querystring');
|
2022-09-16 15:20:44 +00:00
|
|
|
|
|
|
|
|
export function filePathForEnvVars(env: string | undefined): string {
|
|
|
|
|
if (env === 'test') {
|
|
|
|
|
return path.resolve(process.cwd(), '../.env.test');
|
|
|
|
|
} else {
|
|
|
|
|
return path.resolve(process.cwd(), '../.env');
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-02 08:21:48 +00:00
|
|
|
|
2022-12-22 20:39:57 +00:00
|
|
|
export function getEnvVars() {
|
|
|
|
|
let data: any = process.env;
|
|
|
|
|
const envVarsFilePath = filePathForEnvVars(process.env.NODE_ENV);
|
|
|
|
|
|
|
|
|
|
if (fs.existsSync(envVarsFilePath)) {
|
|
|
|
|
data = { ...data, ...dotenv.parse(fs.readFileSync(envVarsFilePath)) };
|
|
|
|
|
}
|
2023-03-21 19:49:13 +00:00
|
|
|
|
2022-12-22 20:39:57 +00:00
|
|
|
data = {
|
|
|
|
|
...data,
|
2023-03-21 19:49:13 +00:00
|
|
|
...((data.DATABASE_URL || data.TOOLJET_DB_URL) && buildDbConfigFromDatabaseURL(data)),
|
2021-08-02 08:21:48 +00:00
|
|
|
};
|
2023-01-09 15:05:24 +00:00
|
|
|
|
2022-12-22 20:39:57 +00:00
|
|
|
return data;
|
2021-08-02 08:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
2023-01-03 07:55:45 +00:00
|
|
|
function buildDbConfigFromDatabaseURL(data): any {
|
2023-03-24 15:24:40 +00:00
|
|
|
const config = buildDbConfigFromUrl(data.DATABASE_URL);
|
|
|
|
|
const TJDBconfig = buildDbConfigFromUrl(data.TOOLJET_DB_URL);
|
2022-12-22 20:39:57 +00:00
|
|
|
|
|
|
|
|
const { value: dbConfig, error } = validateDatabaseConfig({
|
2023-01-03 07:55:45 +00:00
|
|
|
DATABASE_URL: data.DATBASE_URL,
|
2023-03-21 19:49:13 +00:00
|
|
|
PG_HOST: config?.host || data.PG_HOST,
|
|
|
|
|
PG_PORT: config?.port || data.PG_PORT,
|
|
|
|
|
PG_PASS: config?.password || data.PG_PASS,
|
|
|
|
|
PG_USER: config?.user || data.PG_USER,
|
|
|
|
|
PG_DB: config?.database || data.PG_DB,
|
2023-01-09 15:05:24 +00:00
|
|
|
PG_DB_OWNER: data.PG_DB_OWNER,
|
2023-03-21 19:49:13 +00:00
|
|
|
TOOLJET_DB: TJDBconfig?.database || data.TOOLJET_DB,
|
2023-01-09 15:05:24 +00:00
|
|
|
TOOLJET_DB_OWNER: data.TOOLJET_DB_OWNER,
|
2023-03-21 19:49:13 +00:00
|
|
|
TOOLJET_DB_HOST: TJDBconfig?.host || data.TOOLJET_DB_HOST,
|
|
|
|
|
TOOLJET_DB_PORT: TJDBconfig?.port || data.TOOLJET_DB_PORT,
|
|
|
|
|
TOOLJET_DB_PASS: TJDBconfig?.password || data.TOOLJET_DB_PASS,
|
|
|
|
|
TOOLJET_DB_USER: TJDBconfig?.user || data.TOOLJET_DB_USER,
|
2024-04-30 16:19:37 +00:00
|
|
|
SAMPLE_DB: data.SAMPLE_DB || 'sample_db',
|
|
|
|
|
SAMPLE_PG_DB_HOST: config?.host || data.PG_HOST || data.SAMPLE_PG_DB_HOST,
|
|
|
|
|
SAMPLE_PG_DB_PORT: config?.port || data.PG_PORT || data.SAMPLE_PG_DB_PORT,
|
|
|
|
|
SAMPLE_PG_DB_USER: config?.user || data.PG_USER || data.SAMPLE_PG_DB_USER,
|
|
|
|
|
SAMPLE_PG_DB_PASS: config?.password || data.PG_PASS || data.SAMPLE_PG_DB_PASS,
|
2022-12-22 20:39:57 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
throw new Error(`Config validation error: ${error.message}`);
|
|
|
|
|
}
|
|
|
|
|
return removeEmptyKeys(dbConfig);
|
2023-03-21 19:49:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildDbConfigFromUrl(dbURL): any {
|
|
|
|
|
let config: any;
|
|
|
|
|
if (dbURL) {
|
|
|
|
|
const parsedUrl = url.parse(dbURL, false, true);
|
|
|
|
|
config = querystring.parse(parsedUrl.query);
|
|
|
|
|
config.driver = parsedUrl.protocol.replace(/:$/, '');
|
|
|
|
|
|
|
|
|
|
if (parsedUrl.auth) {
|
|
|
|
|
const userPassword = parsedUrl.auth.split(':', 2);
|
|
|
|
|
config.user = userPassword[0];
|
|
|
|
|
|
|
|
|
|
if (userPassword.length > 1) config.password = userPassword[1];
|
|
|
|
|
if (parsedUrl.pathname) config.database = parsedUrl.pathname.replace(/^\//, '').replace(/\/$/, '');
|
|
|
|
|
if (parsedUrl.hostname) config.host = parsedUrl.hostname;
|
|
|
|
|
if (parsedUrl.port) config.port = parsedUrl.port;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return config;
|
2022-12-22 20:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function removeEmptyKeys(obj) {
|
|
|
|
|
return Object.entries(obj)
|
|
|
|
|
.filter(([_, v]) => !isEmpty(v))
|
|
|
|
|
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function validateDatabaseConfig(dbConfig: any): Joi.ValidationResult {
|
2021-08-02 08:21:48 +00:00
|
|
|
const envVarsSchema = Joi.object()
|
|
|
|
|
.keys({
|
|
|
|
|
PG_HOST: Joi.string().default('localhost'),
|
|
|
|
|
PG_PORT: Joi.number().positive().default(5432),
|
|
|
|
|
PG_PASS: Joi.string().default(''),
|
|
|
|
|
PG_USER: Joi.string().required(),
|
2022-12-22 20:39:57 +00:00
|
|
|
PG_DB: Joi.string().default('tooljet_production'),
|
2022-09-16 16:27:33 +00:00
|
|
|
PG_DB_OWNER: Joi.string().default('true'),
|
2024-10-30 12:00:44 +00:00
|
|
|
TOOLJET_DB_HOST: Joi.string().default('localhost'),
|
|
|
|
|
TOOLJET_DB_PORT: Joi.number().positive().default(5432),
|
|
|
|
|
TOOLJET_DB_PASS: Joi.string().default(''),
|
|
|
|
|
TOOLJET_DB_USER: Joi.string().required(),
|
|
|
|
|
TOOLJET_DB: Joi.string().default('tooljet_db'),
|
|
|
|
|
TOOLJET_DB_OWNER: Joi.string().default('true'),
|
|
|
|
|
|
2024-04-30 16:19:37 +00:00
|
|
|
...{
|
|
|
|
|
SAMPLE_PG_DB_HOST: Joi.string().default('localhost'),
|
|
|
|
|
SAMPLE_PG_DB_PORT: Joi.number().positive().default(5432),
|
|
|
|
|
SAMPLE_PG_DB_PASS: Joi.string().default(''),
|
|
|
|
|
SAMPLE_PG_DB_USER: Joi.string().required(),
|
|
|
|
|
SAMPLE_DB: Joi.string().default('sample_db'),
|
|
|
|
|
},
|
2021-08-02 08:21:48 +00:00
|
|
|
})
|
|
|
|
|
.unknown();
|
|
|
|
|
|
2022-12-22 20:39:57 +00:00
|
|
|
return envVarsSchema.validate(dbConfig);
|
2021-08-02 08:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function buildAndValidateDatabaseConfig(): Joi.ValidationResult {
|
2022-12-22 20:39:57 +00:00
|
|
|
const config: any = getEnvVars();
|
|
|
|
|
const dbConfig = {
|
|
|
|
|
PG_HOST: config.PG_HOST,
|
|
|
|
|
PG_PORT: config.PG_PORT,
|
|
|
|
|
PG_PASS: config.PG_PASS,
|
|
|
|
|
PG_USER: config.PG_USER,
|
|
|
|
|
PG_DB: config.PG_DB,
|
|
|
|
|
PG_DB_OWNER: config.PG_DB_OWNER,
|
2023-01-09 15:05:24 +00:00
|
|
|
TOOLJET_DB: config.TOOLJET_DB,
|
|
|
|
|
TOOLJET_DB_HOST: config.TOOLJET_DB_HOST,
|
|
|
|
|
TOOLJET_DB_PORT: config.TOOLJET_DB_PORT,
|
|
|
|
|
TOOLJET_DB_PASS: config.TOOLJET_DB_PASS,
|
|
|
|
|
TOOLJET_DB_USER: config.TOOLJET_DB_USER,
|
|
|
|
|
TOOLJET_DB_OWNER: config.TOOLJET_DB_OWNER,
|
2024-04-30 16:19:37 +00:00
|
|
|
ENABLE_SAMPLE_PG_DB: config.ENABLE_SAMPLE_PG_DB,
|
|
|
|
|
SAMPLE_DB: config.SAMPLE_DB || 'sample_db',
|
|
|
|
|
SAMPLE_PG_DB_HOST: config.SAMPLE_PG_DB_HOST || config.PG_HOST,
|
|
|
|
|
SAMPLE_PG_DB_PORT: config.SAMPLE_PG_DB_PORT || config.PG_PORT,
|
|
|
|
|
SAMPLE_PG_DB_USER: config.SAMPLE_PG_DB_USER || config.PG_USER,
|
|
|
|
|
SAMPLE_PG_DB_PASS: config.SAMPLE_PG_DB_PASS || config.PG_PASS,
|
2022-12-22 20:39:57 +00:00
|
|
|
};
|
2021-08-02 08:21:48 +00:00
|
|
|
|
2022-12-22 20:39:57 +00:00
|
|
|
return validateDatabaseConfig(dbConfig);
|
2021-08-02 08:21:48 +00:00
|
|
|
}
|