datapilot-cli
Version:
Enterprise-grade streaming multi-format data analysis with comprehensive statistical insights and intelligent relationship detection - supports CSV, JSON, Excel, TSV, Parquet - memory-efficient, cross-platform
247 lines • 8.85 kB
JavaScript
;
/**
* Configuration file loader for DataPilot CLI
* Supports multiple configuration formats and environment variable overrides
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigLoader = void 0;
const fs_1 = require("fs");
const path_1 = require("path");
const os_1 = require("os");
class ConfigLoader {
static CONFIG_FILES = [
'.datapilotrc',
'.datapilotrc.json',
'.datapilotrc.yaml',
'.datapilotrc.yml',
'datapilot.config.js',
'datapilot.config.json',
'package.json', // Check for datapilot field
];
static ENV_PREFIX = 'DATAPILOT_';
/**
* Load configuration from files and environment
*/
static async loadConfig(startDir = process.cwd()) {
// 1. Load from configuration files
const fileConfig = await this.loadFromFiles(startDir);
// 2. Load from environment variables
const envConfig = this.loadFromEnvironment();
// 3. Merge configurations (env > local > global)
return this.mergeConfigs(fileConfig, envConfig);
}
/**
* Search for and load configuration files
*/
static async loadFromFiles(startDir) {
const configs = [];
// Search from current directory up to root
let currentDir = startDir;
while (currentDir !== (0, path_1.dirname)(currentDir)) {
const config = await this.loadFromDirectory(currentDir);
if (config) {
configs.push(config);
}
currentDir = (0, path_1.dirname)(currentDir);
}
// Also check home directory
const homeConfig = await this.loadFromDirectory((0, os_1.homedir)());
if (homeConfig) {
configs.push(homeConfig);
}
// Merge all configs (closer to cwd takes precedence)
return configs.reduce((merged, config) => this.mergeConfigs(config, merged), {});
}
/**
* Load configuration from a specific directory
*/
static async loadFromDirectory(dir) {
for (const filename of this.CONFIG_FILES) {
const filepath = (0, path_1.join)(dir, filename);
if ((0, fs_1.existsSync)(filepath)) {
try {
if (filename === 'package.json') {
const pkg = JSON.parse((0, fs_1.readFileSync)(filepath, 'utf8'));
if (pkg.datapilot) {
return pkg.datapilot;
}
}
else if (filename.endsWith('.js')) {
// Dynamic import for JS config files
const config = require(filepath);
return config.default || config;
}
else if (filename.endsWith('.json') || filename === '.datapilotrc') {
return JSON.parse((0, fs_1.readFileSync)(filepath, 'utf8'));
}
else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
// Would need to add yaml parser dependency
console.warn(`YAML config files not yet supported: ${filepath}`);
}
}
catch (error) {
console.warn(`Error loading config from ${filepath}:`, error);
}
}
}
return null;
}
/**
* Load configuration from environment variables
*/
static loadFromEnvironment() {
const config = {
defaults: {},
};
// Map of environment variables to config options
const envMappings = {
OUTPUT: 'output',
OUTPUT_FILE: 'outputFile',
MAX_ROWS: 'maxRows',
MAX_MEMORY: 'maxMemory',
PRIVACY_MODE: 'privacyMode',
VERBOSE: 'verbose',
QUIET: 'quiet',
FORCE: 'force',
DRY_RUN: 'dryRun',
};
for (const [envKey, configKey] of Object.entries(envMappings)) {
const envVar = `${this.ENV_PREFIX}${envKey}`;
const value = process.env[envVar];
if (value !== undefined) {
// Type conversion based on the config key
if (configKey === 'maxRows' || configKey === 'maxMemory') {
config.defaults[configKey] = parseInt(value, 10);
}
else if (configKey === 'verbose' ||
configKey === 'quiet' ||
configKey === 'force' ||
configKey === 'dryRun') {
config.defaults[configKey] = value === 'true' || value === '1';
}
else if (configKey === 'output') {
config.defaults[configKey] = value;
}
else if (configKey === 'privacyMode') {
config.defaults[configKey] = value;
}
else {
config.defaults[configKey] = value;
}
}
}
return config;
}
/**
* Merge two configuration objects
*/
static mergeConfigs(source, target) {
return {
defaults: { ...target.defaults, ...source.defaults },
commands: { ...target.commands, ...source.commands },
environments: { ...target.environments, ...source.environments },
aliases: { ...target.aliases, ...source.aliases },
presets: { ...target.presets, ...source.presets },
};
}
/**
* Apply configuration to CLI options
*/
static applyConfig(options, config, command) {
let merged = { ...options };
// Apply defaults
if (config.defaults) {
merged = { ...config.defaults, ...merged };
}
// Apply command-specific overrides
if (command && config.commands?.[command]) {
merged = { ...config.commands[command], ...merged };
}
// Apply environment-specific settings
const env = process.env.NODE_ENV || 'development';
if (config.environments?.[env]) {
if (config.environments[env].defaults) {
merged = { ...config.environments[env].defaults, ...merged };
}
if (command && config.environments[env].commands?.[command]) {
merged = { ...config.environments[env].commands[command], ...merged };
}
}
// Apply presets if specified in options (Note: preset is not a standard CLIOption)
// This would need to be handled separately through a different mechanism
return merged;
}
/**
* Resolve command aliases
*/
static resolveAlias(alias, config) {
return config.aliases?.[alias] || null;
}
/**
* Get example configuration
*/
static getExampleConfig() {
return {
defaults: {
output: 'markdown',
verbose: false,
privacyMode: 'redacted',
},
commands: {
all: {
maxMemory: 1024,
showProgress: true,
},
eda: {
chunkSize: 1000,
memoryLimit: 512,
},
},
environments: {
production: {
defaults: {
quiet: true,
output: 'json',
privacyMode: 'minimal',
},
},
ci: {
defaults: {
quiet: true,
showProgress: false,
output: 'json',
},
},
},
aliases: {
'quick-check': {
command: 'validate',
options: {
verbose: true,
},
},
'full-report': {
command: 'all',
options: {
output: 'markdown',
verbose: true,
includeEnvironment: true,
},
},
},
presets: {
'low-memory': {
maxMemory: 256,
maxRows: 10000,
},
'high-performance': {
maxMemory: 4096,
parallel: true,
},
},
};
}
}
exports.ConfigLoader = ConfigLoader;
// DataPilotConfig is already exported as an interface above
//# sourceMappingURL=config-loader.js.map