@dreamhorizonorg/sentinel
Version:
Open-source, zero-dependency tool that blocks compromised packages BEFORE download. Built to counter supply chain and credential theft attacks like Shai-Hulud.
127 lines (108 loc) • 3.52 kB
JavaScript
/**
* Configuration loading utilities
* Pure functions for loading and merging configuration
*/
import fs from 'fs';
import path from 'path';
import { CONFIG_FILENAMES, DEFAULT_LOG_MODE, VALID_LOG_MODES } from '../constants/app.constants.mjs';
import { pathExists } from './file.utils.mjs';
/**
* Load configuration from file system
* Searches up the directory tree for config files
*/
export const loadConfig = () => {
let currentDir = process.cwd();
const rootDir = path.parse(currentDir).root;
while (currentDir !== rootDir) {
for (const configFile of CONFIG_FILENAMES) {
const configPath = path.join(currentDir, configFile);
if (pathExists(configPath)) {
try {
const isJsonFile = configFile.endsWith('.json') || configFile.endsWith('rc');
if (isJsonFile) {
const content = fs.readFileSync(configPath, 'utf-8');
return JSON.parse(content);
}
// For JS/MJS files, skip for now (would need dynamic import)
// Users can use JSON config
} catch (error) {
// Ignore parse errors, continue searching
}
}
}
currentDir = path.dirname(currentDir);
}
return {};
};
/**
* Normalize log mode value
*/
export const normalizeLogMode = (logModeArg) => {
if (!logModeArg || typeof logModeArg !== 'string') {
return DEFAULT_LOG_MODE;
}
const normalized = logModeArg.toLowerCase();
if (VALID_LOG_MODES.includes(normalized)) {
return normalized;
}
return DEFAULT_LOG_MODE;
};
/**
* Merge CLI options with config file
* CLI options override config file values
*/
export const mergeConfig = (config, options) => {
const logModeArg = options.logmode ?? options.l ?? config.logMode ?? DEFAULT_LOG_MODE;
const logMode = normalizeLogMode(logModeArg);
// Merge provider config
const providersConfig = config.providers ?? {};
const mergedProviders = { ...providersConfig };
// OSV provider
if (options.enableosv !== undefined) {
mergedProviders.osv = {
...mergedProviders.osv,
enabled: options.enableosv === true || options.enableosv === 'true'
};
}
// GitHub provider
if (options.enablegithub !== undefined) {
mergedProviders.github = {
...mergedProviders.github,
enabled: options.enablegithub === true || options.enablegithub === 'true'
};
}
if (options.githubtoken !== undefined) {
mergedProviders.github = {
...mergedProviders.github,
token: options.githubtoken
};
}
// Snyk provider
if (options.enablesnyk !== undefined) {
mergedProviders.snyk = {
...mergedProviders.snyk,
enabled: options.enablesnyk === true || options.enablesnyk === 'true'
};
}
if (options.snyktoken !== undefined) {
mergedProviders.snyk = {
...mergedProviders.snyk,
token: options.snyktoken,
enabled: true // Auto-enable if token is provided
};
}
return {
...config,
// Data source options (CLI overrides config)
dataSourcePath: options.localdatasource ?? options.datasourcepath ?? config.dataSourcePath,
endpoint: options.remotedatasource ?? options.endpoint ?? config.endpoint,
// Behavior options
skipNpmAudit: options.skipnpmaudit !== undefined
? (options.skipnpmaudit === true || options.skipnpmaudit === 'true')
: (config.skipNpmAudit ?? false),
// Log mode
logMode,
// Providers config
providers: mergedProviders
};
};