Files
cli/ts/mod_services/classes.serviceconfiguration.ts

274 lines
7.7 KiB
TypeScript

import * as plugins from './mod.plugins.js';
import * as helpers from './helpers.js';
import { logger } from '../gitzone.logging.js';
export interface IServiceConfig {
PROJECT_NAME: string;
MONGODB_HOST: string;
MONGODB_NAME: string;
MONGODB_PORT: string;
MONGODB_USER: string;
MONGODB_PASS: string;
MONGODB_URL: string;
S3_HOST: string;
S3_PORT: string;
S3_CONSOLE_PORT: string;
S3_ACCESSKEY: string;
S3_SECRETKEY: string;
S3_BUCKET: string;
S3_ENDPOINT: string;
}
export class ServiceConfiguration {
private configPath: string;
private config: IServiceConfig;
constructor() {
this.configPath = plugins.path.join(process.cwd(), '.nogit', 'env.json');
}
/**
* Load or create the configuration
*/
public async loadOrCreate(): Promise<IServiceConfig> {
await this.ensureNogitDirectory();
if (await this.configExists()) {
await this.loadConfig();
await this.updateMissingFields();
} else {
await this.createDefaultConfig();
}
return this.config;
}
/**
* Get the current configuration
*/
public getConfig(): IServiceConfig {
return this.config;
}
/**
* Save the configuration to file
*/
public async saveConfig(): Promise<void> {
await plugins.smartfile.memory.toFs(
JSON.stringify(this.config, null, 2),
this.configPath
);
}
/**
* Ensure .nogit directory exists
*/
private async ensureNogitDirectory(): Promise<void> {
const nogitPath = plugins.path.join(process.cwd(), '.nogit');
await plugins.smartfile.fs.ensureDir(nogitPath);
}
/**
* Check if configuration file exists
*/
private async configExists(): Promise<boolean> {
return plugins.smartfile.fs.fileExists(this.configPath);
}
/**
* Load configuration from file
*/
private async loadConfig(): Promise<void> {
const configContent = await plugins.smartfile.fs.toStringSync(this.configPath);
this.config = JSON.parse(configContent);
}
/**
* Create default configuration
*/
private async createDefaultConfig(): Promise<void> {
const projectName = helpers.getProjectName();
const mongoPort = await helpers.getRandomAvailablePort();
const s3Port = await helpers.getRandomAvailablePort();
let s3ConsolePort = s3Port + 1;
// Ensure console port is also available
while (!(await helpers.isPortAvailable(s3ConsolePort))) {
s3ConsolePort++;
}
const mongoUser = 'defaultadmin';
const mongoPass = 'defaultpass';
const mongoHost = 'localhost';
const mongoName = projectName;
const mongoPortStr = mongoPort.toString();
const s3Host = 'localhost';
const s3PortStr = s3Port.toString();
this.config = {
PROJECT_NAME: projectName,
MONGODB_HOST: mongoHost,
MONGODB_NAME: mongoName,
MONGODB_PORT: mongoPortStr,
MONGODB_USER: mongoUser,
MONGODB_PASS: mongoPass,
MONGODB_URL: `mongodb://${mongoUser}:${mongoPass}@${mongoHost}:${mongoPortStr}/${mongoName}?authSource=admin`,
S3_HOST: s3Host,
S3_PORT: s3PortStr,
S3_CONSOLE_PORT: s3ConsolePort.toString(),
S3_ACCESSKEY: 'defaultadmin',
S3_SECRETKEY: 'defaultpass',
S3_BUCKET: `${projectName}-documents`,
S3_ENDPOINT: `http://${s3Host}:${s3PortStr}`
};
await this.saveConfig();
logger.log('ok', '✅ Created .nogit/env.json with project defaults');
logger.log('info', `📍 MongoDB port: ${mongoPort}`);
logger.log('info', `📍 S3 API port: ${s3Port}`);
logger.log('info', `📍 S3 Console port: ${s3ConsolePort}`);
}
/**
* Update missing fields in existing configuration
*/
private async updateMissingFields(): Promise<void> {
const projectName = helpers.getProjectName();
let updated = false;
const fieldsAdded: string[] = [];
// Check and add missing fields
if (!this.config.PROJECT_NAME) {
this.config.PROJECT_NAME = projectName;
fieldsAdded.push('PROJECT_NAME');
updated = true;
}
if (!this.config.MONGODB_HOST) {
this.config.MONGODB_HOST = 'localhost';
fieldsAdded.push('MONGODB_HOST');
updated = true;
}
if (!this.config.MONGODB_NAME) {
this.config.MONGODB_NAME = projectName;
fieldsAdded.push('MONGODB_NAME');
updated = true;
}
if (!this.config.MONGODB_PORT) {
const port = await helpers.getRandomAvailablePort();
this.config.MONGODB_PORT = port.toString();
fieldsAdded.push(`MONGODB_PORT(${port})`);
updated = true;
}
if (!this.config.MONGODB_USER) {
this.config.MONGODB_USER = 'defaultadmin';
fieldsAdded.push('MONGODB_USER');
updated = true;
}
if (!this.config.MONGODB_PASS) {
this.config.MONGODB_PASS = 'defaultpass';
fieldsAdded.push('MONGODB_PASS');
updated = true;
}
// Always update MONGODB_URL based on current settings
const oldUrl = this.config.MONGODB_URL;
this.config.MONGODB_URL = `mongodb://${this.config.MONGODB_USER}:${this.config.MONGODB_PASS}@${this.config.MONGODB_HOST}:${this.config.MONGODB_PORT}/${this.config.MONGODB_NAME}?authSource=admin`;
if (oldUrl !== this.config.MONGODB_URL) {
fieldsAdded.push('MONGODB_URL');
updated = true;
}
if (!this.config.S3_HOST) {
this.config.S3_HOST = 'localhost';
fieldsAdded.push('S3_HOST');
updated = true;
}
if (!this.config.S3_PORT) {
const port = await helpers.getRandomAvailablePort();
this.config.S3_PORT = port.toString();
fieldsAdded.push(`S3_PORT(${port})`);
updated = true;
}
if (!this.config.S3_CONSOLE_PORT) {
const s3Port = parseInt(this.config.S3_PORT);
let consolePort = s3Port + 1;
while (!(await helpers.isPortAvailable(consolePort))) {
consolePort++;
}
this.config.S3_CONSOLE_PORT = consolePort.toString();
fieldsAdded.push(`S3_CONSOLE_PORT(${consolePort})`);
updated = true;
}
if (!this.config.S3_ACCESSKEY) {
this.config.S3_ACCESSKEY = 'defaultadmin';
fieldsAdded.push('S3_ACCESSKEY');
updated = true;
}
if (!this.config.S3_SECRETKEY) {
this.config.S3_SECRETKEY = 'defaultpass';
fieldsAdded.push('S3_SECRETKEY');
updated = true;
}
if (!this.config.S3_BUCKET) {
this.config.S3_BUCKET = `${projectName}-documents`;
fieldsAdded.push('S3_BUCKET');
updated = true;
}
// Always update S3_ENDPOINT based on current settings
const oldEndpoint = this.config.S3_ENDPOINT;
this.config.S3_ENDPOINT = `http://${this.config.S3_HOST}:${this.config.S3_PORT}`;
if (oldEndpoint !== this.config.S3_ENDPOINT) {
fieldsAdded.push('S3_ENDPOINT');
updated = true;
}
if (updated) {
await this.saveConfig();
logger.log('ok', `✅ Added missing fields: ${fieldsAdded.join(', ')}`);
} else {
logger.log('ok', '✅ Configuration complete');
}
}
/**
* Get MongoDB connection string
*/
public getMongoConnectionString(useNetworkIp: boolean = false): string {
const host = useNetworkIp ? '${networkIp}' : this.config.MONGODB_HOST;
return `mongodb://${this.config.MONGODB_USER}:${this.config.MONGODB_PASS}@${host}:${this.config.MONGODB_PORT}/${this.config.MONGODB_NAME}?authSource=admin`;
}
/**
* Get container names
*/
public getContainerNames() {
return {
mongo: `${this.config.PROJECT_NAME}-mongodb`,
minio: `${this.config.PROJECT_NAME}-minio`
};
}
/**
* Get data directories
*/
public getDataDirectories() {
return {
mongo: plugins.path.join(process.cwd(), '.nogit', 'mongodata'),
minio: plugins.path.join(process.cwd(), '.nogit', 'miniodata')
};
}
}