chromancer
Version:
A powerful command-line interface for automating Chrome browser using Playwright. Perfect for web scraping, automation, testing, and browser workflows.
149 lines (148 loc) • 4.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.config = void 0;
exports.applyConfigToFlags = applyConfigToFlags;
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs/promises"));
const path = tslib_1.__importStar(require("path"));
const os = tslib_1.__importStar(require("os"));
class ConfigManager {
configPath;
config;
constructor() {
this.configPath = path.join(os.homedir(), '.chromancer.json');
}
async load() {
if (this.config) {
return this.config;
}
try {
const content = await fs.readFile(this.configPath, 'utf-8');
this.config = JSON.parse(content);
return this.config;
}
catch (error) {
// Return default config if file doesn't exist
this.config = this.getDefaultConfig();
return this.config;
}
}
async save(config) {
this.config = config;
await fs.writeFile(this.configPath, JSON.stringify(config, null, 2));
}
async get(path, defaultValue) {
const config = await this.load();
const keys = path.split('.');
let value = config;
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = value[key];
}
else {
return defaultValue;
}
}
return value;
}
async set(path, value) {
const config = await this.load();
const keys = path.split('.');
let current = config;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!current[key] || typeof current[key] !== 'object') {
current[key] = {};
}
current = current[key];
}
current[keys[keys.length - 1]] = value;
await this.save(config);
}
getDefaultConfig() {
return {
chrome: {
port: 9222,
host: 'localhost',
defaultTimeout: 30000,
launchOptions: {
headless: false,
args: [],
},
},
commands: {
screenshot: {
path: './screenshots',
fullPage: true,
type: 'png',
},
pdf: {
path: './pdfs',
format: 'A4',
landscape: false,
},
export: {
path: './exports',
defaultFormat: 'json',
},
record: {
outputPath: './recordings',
maxDuration: 300000, // 5 minutes
},
},
workflows: {
continueOnError: false,
variablePrefix: '${',
variableSuffix: '}',
defaultTimeout: 30000,
},
ui: {
colorOutput: true,
verboseErrors: true,
showTips: true,
progressIndicators: true,
},
aliases: {
'g': 'go',
'n': 'navigate',
's': 'screenshot',
'c': 'click',
't': 'type',
'w': 'wait',
'e': 'evaluate',
},
};
}
async reset() {
this.config = this.getDefaultConfig();
await this.save(this.config);
}
getConfigPath() {
return this.configPath;
}
}
// Singleton instance
exports.config = new ConfigManager();
// Helper to apply config to command flags
async function applyConfigToFlags(command, flags) {
const configData = await exports.config.load();
// Apply command-specific config
const commandConfig = configData.commands?.[command];
if (commandConfig) {
Object.entries(commandConfig).forEach(([key, value]) => {
if (!(key in flags) || flags[key] === undefined) {
flags[key] = value;
}
});
}
// Apply global Chrome config
if (configData.chrome) {
if (!flags.port && configData.chrome.port) {
flags.port = configData.chrome.port;
}
if (!flags.host && configData.chrome.host) {
flags.host = configData.chrome.host;
}
}
return flags;
}