@deepguide-ai/dg
Version:
Self-testing CLI documentation tool that generates interactive terminal demos
155 lines • 5.41 kB
JavaScript
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { dirname, join } from 'path';
import { dgLogger as logger } from './logger.js';
const DEFAULT_CONFIG = {
version: '0.1.0',
project: '',
outputDir: '.dg',
updated: new Date().toISOString()
};
export function getConfigPath(cwd = process.cwd()) {
return join(cwd, '.dg', 'config.json');
}
export function configExists(cwd = process.cwd()) {
return existsSync(getConfigPath(cwd));
}
export function readConfig(cwd = process.cwd()) {
const configPath = join(cwd, '.dg', 'config.json');
if (!existsSync(configPath)) {
return null;
}
try {
const config = JSON.parse(readFileSync(configPath, 'utf8'));
return config;
}
catch (error) {
logger.error('Failed to read config', error);
return null;
}
}
export function writeConfig(config, cwd = process.cwd()) {
const configPath = join(cwd, '.dg', 'config.json');
logger.debug('Attempting to write config', { configPath, config });
// Ensure parent directory exists
const configDir = dirname(configPath);
logger.debug('Checking config directory', { configDir });
if (!existsSync(configDir)) {
logger.debug('Creating config directory', { configDir });
mkdirSync(configDir, { recursive: true });
}
// Validate config before writing
if (!config.project || !config.version || !config.outputDir) {
const error = new Error('Invalid config object - missing required fields');
logger.error(error.message, {
hasProject: !!config.project,
hasVersion: !!config.version,
hasOutputDir: !!config.outputDir,
config
});
throw error;
}
// Write config with pretty formatting
const configStr = JSON.stringify(config, null, 2);
logger.debug('Writing config file', { configPath, configStr });
writeFileSync(configPath, configStr);
logger.debug('Config written successfully', { path: configPath });
}
export function createConfig(projectName, cwd = process.cwd()) {
const config = {
...DEFAULT_CONFIG,
project: projectName,
casts: []
};
return config;
}
export function ensureDirectoryStructure(outputDir = '.dg', cwd = process.cwd()) {
try {
const basePath = join(cwd, outputDir);
const castsPath = join(basePath, 'casts');
const svgPath = join(basePath, 'svg');
const snippetsPath = join(basePath, 'snippets');
mkdirSync(basePath, { recursive: true });
mkdirSync(castsPath, { recursive: true });
mkdirSync(svgPath, { recursive: true });
mkdirSync(snippetsPath, { recursive: true });
return true;
}
catch (error) {
console.error('Failed to create directory structure:', error.message);
return false;
}
}
export function getAllCasts(cwd = process.cwd()) {
const config = readConfig(cwd);
return config?.casts || [];
}
export function addCast(cast, cwd = process.cwd()) {
logger.debug('Adding cast', { cast, cwd });
// First ensure the directory structure exists
if (!ensureDirectoryStructure('.dg', cwd)) {
throw new Error('Failed to create directory structure');
}
// If config doesn't exist, create it with default values
let config = readConfig(cwd);
if (!config) {
logger.debug('No existing config found, creating new one', { cwd });
config = createConfig(detectProjectName(cwd), cwd);
writeConfig(config, cwd);
}
logger.debug('Current config before adding cast', {
config,
configKeys: Object.keys(config),
configType: typeof config,
configIsArray: Array.isArray(config),
configProto: Object.getPrototypeOf(config)
});
config.casts = config.casts || [];
config.casts.push(cast);
config.updated = new Date().toISOString();
logger.debug('Updated config with new cast', {
config,
configKeys: Object.keys(config),
configType: typeof config,
configIsArray: Array.isArray(config),
configProto: Object.getPrototypeOf(config)
});
writeConfig(config, cwd);
}
export function updateCast(cast, cwd = process.cwd()) {
const config = readConfig(cwd);
if (!config) {
throw new Error('No config found');
}
const index = config.casts.findIndex(c => c.name === cast.name);
if (index === -1) {
throw new Error(`Cast ${cast.name} not found`);
}
config.casts[index] = cast;
config.updated = new Date().toISOString();
writeConfig(config, cwd);
}
export function getCast(name, cwd = process.cwd()) {
const config = readConfig(cwd);
if (!config) {
return null;
}
return config.casts.find(c => c.name === name) || null;
}
export function detectProjectName(cwd = process.cwd()) {
try {
// Try to read package.json
const packagePath = join(cwd, 'package.json');
if (existsSync(packagePath)) {
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
if (pkg.name) {
return pkg.name.replace(/^@[^/]+\//, ''); // Remove scope
}
}
// Fallback to directory name
return cwd.split('/').pop() || 'my-cli';
}
catch {
return 'my-cli';
}
}
//# sourceMappingURL=config.js.map