A powerful CLI tool to dynamically modify YAML configuration files using JavaScript. Perfect for transforming proxy configurations (Clash, Clash Verge Rev, Mihomo, etc.) or any YAML-based configuration files.
- 🚀 JavaScript Execution: Write transformation logic in JavaScript
- 📝 YAML Support: Load and save YAML configuration files
- 🔄 Configuration Transformation: Dynamically modify configuration objects
- 🛡️ Safe Execution: Sandboxed script execution with resource limits
- 📊 Script Logging: Capture console output from transformation scripts
- 🔧 Flexible API: Use as CLI tool or integrate as a library
- ✅ Well-tested: Comprehensive test suite included
git clone https://github.com/yourusername/mihomo-config-tran.git
cd mihomo-config-tran
cargo build --release
./target/release/config-script-transform --helpTransform a configuration file using a JavaScript script:
config-script-transform \
--config clash.yaml \
--script enhance.js \
--output final_config.yamlUSAGE:
config-script-transform [OPTIONS] --config <FILE> --script <FILE>
OPTIONS:
-c, --config <FILE> Path to the YAML configuration file
-s, --script <FILE> Path to the JavaScript transformation script
-o, --output <FILE> Path to save the transformed configuration
-S, --inline-script <SCRIPT> Inline JavaScript script (alternative to --script)
-v, --verbose Enable verbose logging
-h, --help Print help information
--version Print version information
config-script-transform \
--config examples/clash_config.yaml \
--script examples/enhance.js \
--output output.yamlconfig-script-transform \
--config clash.yaml \
--script transform.jsconfig-script-transform \
--config clash.yaml \
--inline-script 'function main(config) { config.mode = "rule"; return config; }'config-script-transform \
--config clash.yaml \
--script enhance.js \
--output result.yaml \
--verboseYour transformation script must define a main(config, name) function:
function main(config, name) {
// Your transformation code here
config.port = 8080;
config["log-level"] = "debug";
console.log("Transformation complete");
return config;
}Available console methods for logging:
console.log(data) // Log message
console.info(data) // Info message
console.warn(data) // Warning message
console.error(data) // Error message
console.debug(data) // Debug message
console.table(data) // Table outputfunction main(config, name) {
config["log-level"] = "debug";
config["allow-lan"] = false;
config.mode = "rule";
console.log("Configuration modified");
return config;
}function main(config, name) {
// Add a new proxy
if (!Array.isArray(config.proxies)) {
config.proxies = [];
}
config.proxies.push({
name: "NewProxy",
type: "ss",
server: "example.com",
port: 8388,
cipher: "aes-256-gcm",
password: "password"
});
// Filter out disabled proxies
config.proxies = config.proxies.filter(p => p.enabled !== false);
console.log(`Total proxies: ${config.proxies.length}`);
return config;
}function main(config, name) {
if (Array.isArray(config.rules)) {
// Add rules at the beginning
config.rules.unshift("DOMAIN,custom.com,Proxy");
// Remove specific rules
config.rules = config.rules.filter(r => !r.includes("REJECT"));
console.log(`Total rules: ${config.rules.length}`);
}
return config;
}See examples/filter_proxies.js for a complex example that:
- Categorizes proxies by type
- Creates dynamic proxy groups
- Adds fallback groups
- Updates rules accordingly
The script executor includes several security measures:
- Memory Limits: Maximum 1000 log outputs, 1MB total log size
- JSON Size Limits: Maximum 10MB configuration size
- Sandboxed Execution: Scripts have no file system or network access
- Error Handling: Invalid scripts return the original configuration
You can also use this as a Rust library:
use config_script_transform::ConfigTransform;
fn main() -> anyhow::Result<()> {
let transformer = ConfigTransform::new();
// Load configuration and script
let config = ConfigTransform::load_config("config.yaml")?;
let script = ConfigTransform::load_script("script.js")?;
// Transform
let (result, logs) = transformer.transform_with_script(&config, &script, "script.js")?;
// Save result
ConfigTransform::save_config(&result, "output.yaml")?;
Ok(())
}Run the test suite:
cargo testRun with verbose output:
cargo test -- --nocapturemihomo-config-tran/
├── src/
│ ├── lib.rs # Main library
│ ├── main.rs # CLI application
│ ├── executor.rs # JavaScript script executor
│ └── config.rs # Configuration handling
├── examples/
│ ├── clash_config.yaml # Example configuration
│ ├── enhance.js # Example transformation script
│ └── filter_proxies.js # Advanced example
├── Cargo.toml
└── README.md
- boa_engine: JavaScript execution engine
- serde_yaml: YAML parsing and serialization
- serde_json: JSON processing
- clap: Command-line argument parsing
- anyhow: Error handling
- log/env_logger: Logging framework
- Script execution is typically very fast (<100ms for most configurations)
- Configuration size limit: 10MB (can be customized)
- Safe for processing large proxy configurations
- Scripts cannot access the file system
- Scripts cannot make network requests
- Maximum script output: 1MB, 1000 log entries
- Maximum JSON configuration size: 10MB
GPL-3.0 (same as Clash Verge Rev)
Contributions are welcome! Please feel free to submit a Pull Request.
- Clash Verge Rev - GUI client for Clash
- Mihomo - Proxy software
- Clash - Original Clash project
This project extracts and adapts the JavaScript transformation functionality from Clash Verge Rev, making it available as a standalone tool.