@citrineos/base
Version:
The base module for OCPP v2.0.1 including all interfaces. This module is not intended to be used directly, but rather as a dependency for other modules.
179 lines • 7 kB
JavaScript
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
//
// SPDX-License-Identifier: Apache-2.0
import { z } from 'zod';
import { BOOTSTRAP_CONFIG_ENV_VAR_PREFIX } from './defineConfig.js';
// Bootstrap schema contains what's needed to start the application
export const bootstrapConfigSchema = z.object({
configFileName: z.string().default('config.json'),
configDir: z.string().optional(),
// Database configuration
database: z.object({
host: z.string().default('localhost'),
port: z.number().int().positive().default(5432),
database: z.string().default('citrine'),
dialect: z.string().default('postgres'),
username: z.string().default('citrine'),
password: z.string().default('citrine'),
pool: z
.object({
max: z.number().int().positive().optional(),
min: z.number().int().nonnegative().optional(),
acquire: z.number().int().positive().optional(),
idle: z.number().int().positive().optional(),
})
.optional(),
sync: z.boolean().default(false),
alter: z.boolean().default(false),
force: z.boolean().default(false),
maxRetries: z.number().int().positive().default(3),
retryDelay: z.number().int().positive().default(1000),
ssl: z
.object({
require: z.boolean().optional(),
rejectUnauthorized: z.boolean().optional(),
ca: z.string().optional(),
})
.optional(),
}),
// File access configuration
fileAccess: z
.object({
type: z.enum(['local', 's3', 'gcp']),
local: z
.object({
defaultFilePath: z.string().default('data'),
})
.optional(),
s3: z
.object({
region: z.string().optional(),
endpoint: z.string().optional(),
defaultBucketName: z.string().default('citrineos-s3-bucket'),
s3ForcePathStyle: z.boolean().default(true),
accessKeyId: z.string().optional(),
secretAccessKey: z.string().optional(),
})
.optional(),
gcp: z
.object({
projectId: z.string(),
credentials: z.object().optional(),
})
.optional(),
})
.refine((obj) => {
// Ensure the selected type has corresponding config
switch (obj.type) {
case 'local':
return !!obj.local;
case 's3':
return !!obj.s3;
case 'gcp':
return !!obj.gcp;
default:
return false;
}
}, {
message: 'Configuration for the selected file access type must be provided',
}),
});
/**
* Helper function to load environment variables based on prefix
*/
function getEnvVarValue(key) {
const envKey = `${BOOTSTRAP_CONFIG_ENV_VAR_PREFIX}${key}`.toUpperCase();
return process.env[envKey];
}
/**
* Parse a potentially JSON-formatted environment variable
*/
function parseEnvValue(value) {
try {
return JSON.parse(value);
}
catch {
return value;
}
}
/**
* Load bootstrap configuration from environment variables
*/
export function loadBootstrapConfig() {
const config = {
configFileName: getEnvVarValue('config_filename') || 'config.json',
configDir: getEnvVarValue('config_dir'),
// Database configuration
database: {
host: getEnvVarValue('database_host'),
port: getEnvVarValue('database_port') && parseInt(getEnvVarValue('database_port'), 10),
database: getEnvVarValue('database_name'),
dialect: getEnvVarValue('database_dialect'),
username: getEnvVarValue('database_username'),
password: getEnvVarValue('database_password'),
sync: getEnvVarValue('database_sync') && parseEnvValue(getEnvVarValue('database_sync')),
alter: getEnvVarValue('database_alter') && parseEnvValue(getEnvVarValue('database_alter')),
force: getEnvVarValue('database_force') && parseEnvValue(getEnvVarValue('database_force')),
maxRetries: getEnvVarValue('database_max_retries') &&
parseInt(getEnvVarValue('database_max_retries'), 10),
retryDelay: getEnvVarValue('database_retry_delay') &&
parseInt(getEnvVarValue('database_retry_delay'), 10),
},
fileAccess: {
type: getEnvVarValue('file_access_type') || 'local',
},
};
const pool = {
max: getEnvVarValue('database_pool_max') && parseInt(getEnvVarValue('database_pool_max'), 10),
min: getEnvVarValue('database_pool_min') && parseInt(getEnvVarValue('database_pool_min'), 10),
acquire: getEnvVarValue('database_pool_acquire') &&
parseInt(getEnvVarValue('database_pool_acquire'), 10),
idle: getEnvVarValue('database_pool_idle') && parseInt(getEnvVarValue('database_pool_idle'), 10),
};
if (Object.keys(pool).length > 0) {
config.database.pool = pool;
}
const sslRequire = getEnvVarValue('database_ssl_require');
if (sslRequire !== undefined) {
config.database.ssl = {
require: parseEnvValue(sslRequire),
rejectUnauthorized: getEnvVarValue('database_ssl_reject_unauthorized') !== undefined
? parseEnvValue(getEnvVarValue('database_ssl_reject_unauthorized'))
: undefined,
ca: getEnvVarValue('database_ssl_ca'),
};
}
// File access configuration
switch (config.fileAccess.type) {
case 'local':
config.fileAccess.local = {
defaultFilePath: getEnvVarValue('file_access_local_default_file_path'),
};
break;
case 's3':
config.fileAccess.s3 = {
region: getEnvVarValue('file_access_s3_region'),
endpoint: getEnvVarValue('file_access_s3_endpoint'),
defaultBucketName: getEnvVarValue('file_access_s3_default_bucket_name'),
s3ForcePathStyle: getEnvVarValue('file_access_s3_force_path_style') &&
parseEnvValue(getEnvVarValue('file_access_s3_force_path_style')),
accessKeyId: getEnvVarValue('file_access_s3_access_key_id'),
secretAccessKey: getEnvVarValue('file_access_s3_secret_access_key'),
};
break;
case 'gcp':
config.fileAccess.gcp = {
projectId: getEnvVarValue('file_access_gcp_project_id'),
credentials: getEnvVarValue('file_access_gcp_credentials'),
};
break;
}
try {
return bootstrapConfigSchema.parse(config);
}
catch (error) {
console.error('Bootstrap configuration validation failed:', error);
throw error;
}
}
//# sourceMappingURL=bootstrap.config.js.map