/**
* Environment configuration utilities
* Handles command-line arguments, environment variables, and .env files
*/
import { config as loadDotEnv } from "dotenv";
import { findConfigFile, loadTomlConfig } from "./toml-loader.js";
import type { TomlConfig, SourceConfig, ProviderType } from "../types/config.js";
// Load .env file
loadDotEnv();
/**
* Parse command line arguments
*/
function parseArgs(): Map<string, string> {
const args = new Map<string, string>();
for (const arg of process.argv.slice(2)) {
if (arg.startsWith("--")) {
const [key, ...valueParts] = arg.slice(2).split("=");
args.set(key, valueParts.join("=") || "true");
}
}
return args;
}
const cliArgs = parseArgs();
/**
* Resolve transport type (stdio or http)
*/
export function resolveTransport(): { type: "stdio" | "http"; source: string } {
// Check CLI argument first
const transportArg = cliArgs.get("transport");
if (transportArg === "http" || transportArg === "stdio") {
return { type: transportArg, source: "CLI argument" };
}
// Check environment variable
const transportEnv = process.env.OSSHUB_TRANSPORT;
if (transportEnv === "http" || transportEnv === "stdio") {
return { type: transportEnv, source: "environment variable" };
}
// Default to stdio
return { type: "stdio", source: "default" };
}
/**
* Resolve HTTP port
*/
export function resolvePort(): { port: number; source: string } {
// Check CLI argument
const portArg = cliArgs.get("port");
if (portArg) {
const port = parseInt(portArg, 10);
if (!isNaN(port)) {
return { port, source: "CLI argument" };
}
}
// Check environment variable
const portEnv = process.env.OSSHUB_PORT || process.env.PORT;
if (portEnv) {
const port = parseInt(portEnv, 10);
if (!isNaN(port)) {
return { port, source: "environment variable" };
}
}
// Default port
return { port: 8080, source: "default" };
}
/**
* Resolve source configurations
*/
export async function resolveSourceConfigs(): Promise<{
sources: SourceConfig[];
tools?: any[];
source: string;
} | null> {
// 1. Check for TOML config file
const configPath = cliArgs.get("config");
const configFile = findConfigFile(configPath);
if (configFile) {
const config = loadTomlConfig(configFile);
if (config.sources && config.sources.length > 0) {
return {
sources: config.sources,
tools: config.tools,
source: `TOML config: ${configFile}`,
};
}
}
// 2. Check for environment variables (single source)
const envSource = buildSourceFromEnv();
if (envSource) {
return {
sources: [envSource],
source: "environment variables",
};
}
return null;
}
/**
* Build a single source configuration from environment variables
*/
function buildSourceFromEnv(): SourceConfig | null {
const type = process.env.OSSHUB_TYPE as ProviderType;
const endpoint = process.env.OSSHUB_ENDPOINT;
const accessKey = process.env.OSSHUB_ACCESS_KEY;
const secretKey = process.env.OSSHUB_SECRET_KEY;
if (!type || !endpoint || !accessKey || !secretKey) {
return null;
}
return {
id: "default",
type,
endpoint,
access_key: accessKey,
secret_key: secretKey,
region: process.env.OSSHUB_REGION,
default_bucket: process.env.OSSHUB_DEFAULT_BUCKET,
connection_timeout: process.env.OSSHUB_TIMEOUT
? parseInt(process.env.OSSHUB_TIMEOUT, 10)
: undefined,
security_token: process.env.OSSHUB_SECURITY_TOKEN,
ssl: process.env.OSSHUB_SSL !== "false",
};
}
/**
* Redact sensitive information from source config for logging
*/
export function redactSourceConfig(source: SourceConfig): string {
const masked = {
...source,
access_key: source.access_key.substring(0, 4) + "****",
secret_key: "****",
security_token: source.security_token ? "****" : undefined,
};
return `${masked.id} (${masked.type}): ${masked.endpoint}`;
}