@bramato/openrouter-mock-generator
Version:
AI-powered mock data generator using OpenRouter API with JSON mode support
743 lines ⢠33.8 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("dotenv/config");
const fs_1 = require("fs");
const path_1 = require("path");
const promises_1 = __importDefault(require("readline/promises"));
const openrouter_agents_1 = require("openrouter-agents");
const ENV_FILE_PATH = (0, path_1.join)(process.cwd(), '.env');
const ENV_BACKUP_PATH = (0, path_1.join)(process.cwd(), '.env.backup');
// Validation patterns (only for format validation, not content)
const VALIDATION_PATTERNS = {
AWS_REGION: /^[a-z0-9-]+$/,
AWS_S3_BUCKET_NAME: /^[a-z0-9.-]{3,63}$/,
DO_SPACES_REGION: /^[a-z0-9-]+$/,
DO_SPACES_NAME: /^[a-z0-9-]{3,63}$/,
};
class InitWizard {
constructor() {
this.rl = promises_1.default.createInterface({
input: process.stdin,
output: process.stdout,
});
this.api = new openrouter_agents_1.OpenRouterAPI();
}
async run() {
try {
console.log('š¤ OpenRouter AI Tools Configuration\\n');
console.log('This wizard will help you set up your OpenRouter API connection.\\n');
// Create backup of existing .env file
await this.createBackupIfNeeded();
const config = await this.collectConfiguration();
await this.writeConfiguration(config);
console.log('\\nā
Configuration completed successfully!');
console.log('\\nš You can now use the AI mock generator:');
console.log(' ai-generate-mock <input.json> --count 50');
const hasImageConfig = config.HUGGINGFACE_API_KEY || config.STORAGE_PROVIDER;
if (hasImageConfig) {
console.log(' ai-generate-mock <input.json> --images --count 20 # With AI image processing');
}
console.log('');
}
catch (error) {
console.error('\\nā Configuration failed:', error instanceof Error ? error.message : 'Unknown error');
// Attempt to restore backup if configuration failed
await this.restoreBackupIfNeeded();
process.exit(1);
}
finally {
this.rl.close();
}
}
async collectConfiguration() {
try {
// Step 1: API Key
const apiKey = await this.getApiKey();
// Step 2: Model Selection
const models = await this.selectModels();
// Step 3: Image Processing Configuration (optional)
const imageConfig = await this.configureImageProcessing();
return {
OPENROUTER_API_KEY: apiKey,
OPENROUTER_DEFAULT_MODEL: models.default,
OPENROUTER_MOCK_GENERATOR_MODEL: models.mockGenerator,
...imageConfig,
};
}
catch (error) {
throw new Error(`Configuration collection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async getApiKey() {
try {
console.log('Step 1: OpenRouter API Key\\n');
console.log('š Get your API key from: \\x1b[36mhttps://openrouter.ai/settings/keys\\x1b[0m');
console.log(' (Ctrl/Cmd + Click to open in browser)\\n');
const existingKey = this.getExistingApiKey();
if (existingKey) {
const keep = await this.askQuestion(`Found existing API key (${this.maskApiKey(existingKey)}). Keep it? (y/n) `);
if (keep.toLowerCase() === 'y' || keep.toLowerCase() === 'yes') {
return existingKey;
}
}
let apiKey = '';
let attempts = 0;
const maxAttempts = 3;
while (!apiKey && attempts < maxAttempts) {
apiKey = await this.askSecureQuestion('Enter your OpenRouter API key: ');
if (!apiKey.trim()) {
console.log('ā API key cannot be empty.');
attempts++;
continue;
}
// API key accepted as-is, no format validation
break;
}
if (!apiKey) {
throw new Error('Failed to get valid API key after maximum attempts');
}
return apiKey;
}
catch (error) {
throw new Error(`API key collection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async selectModels() {
try {
console.log('\\nStep 2: Model Selection');
console.log('Different services can use different models for optimal performance.\\n');
console.log('š Fetching JSON-capable models from OpenRouter...');
let models = [];
try {
models = await this.api.fetchAvailableModels(true);
console.log(`\\nā
Found ${models.length} JSON-capable models\\n`);
}
catch (error) {
console.log(`\\nā ļø Failed to fetch models from OpenRouter: ${error instanceof Error ? error.message : 'Unknown error'}`);
console.log('Using fallback models...\\n');
models = this.api.getFallbackModels(true);
}
if (models.length === 0) {
console.log('ā ļø No models available. Using default configuration.');
return {
default: 'anthropic/claude-3.5-sonnet',
mockGenerator: undefined,
};
}
const defaultModel = await this.selectModelFromCategories(models, 'default');
const mockModel = await this.selectModelFromCategories(models, 'mock generator');
return {
default: defaultModel,
mockGenerator: mockModel,
};
}
catch (error) {
throw new Error(`Model selection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async selectModelFromCategories(models, serviceType) {
console.log(`\\nšÆ Select model for ${serviceType}:`);
const categories = this.categorizeModels(models);
let currentIndex = 1;
categories.forEach(category => {
console.log(`\\nš ${category.name}`);
console.log(` ${category.description}`);
category.models.forEach((model, index) => {
console.log(` ${currentIndex++}. ${this.api.formatModelForDisplay(model)}`);
});
});
console.log(`\\n ${currentIndex++}. Custom (enter your own model ID)`);
console.log(` ${currentIndex++}. Skip (use default: ${categories[0]?.models[0]?.name || 'Claude 3.5 Sonnet'})`);
const choice = await this.askQuestion(`\\nChoose model (1-${currentIndex - 1}): `);
const choiceNum = parseInt(choice);
if (isNaN(choiceNum) || choiceNum < 1 || choiceNum > currentIndex - 1) {
console.log('Invalid choice, using default.');
return categories[0]?.models[0]?.id;
}
// Handle custom and skip options
if (choiceNum === currentIndex - 2) {
// Custom
const customModel = await this.askQuestion('Enter model ID: ');
return customModel.trim() || undefined;
}
if (choiceNum === currentIndex - 1) {
// Skip
return undefined;
}
// Find the selected model
let selectedModel;
let currentModelIndex = 1;
for (const category of categories) {
for (const model of category.models) {
if (currentModelIndex === choiceNum) {
selectedModel = model;
break;
}
currentModelIndex++;
}
if (selectedModel)
break;
}
return selectedModel?.id;
}
async getHuggingFaceApiKey() {
try {
console.log('\\nš¤ Hugging Face API Configuration');
console.log('Hugging Face provides the AI models for image generation (FLUX.1-dev, Qwen-Image).\\n');
console.log('š Create a token at: \\x1b[36mhttps://huggingface.co/settings/tokens\\x1b[0m');
console.log(' ⢠Select "Read" access level');
console.log(' ⢠Enable "Make calls to the serverless Inference API"\\n');
const useHF = await this.askQuestion('Do you want to configure Hugging Face API key? (y/n) ');
if (useHF.toLowerCase() !== 'y' && useHF.toLowerCase() !== 'yes') {
console.log(' Skipping Hugging Face API key. Image generation will use free tier with rate limits.');
return undefined;
}
const existingKey = this.getExistingHuggingFaceKey();
if (existingKey) {
const keep = await this.askQuestion(`Found existing HF token (${this.maskApiKey(existingKey)}). Keep it? (y/n) `);
if (keep.toLowerCase() === 'y' || keep.toLowerCase() === 'yes') {
return existingKey;
}
}
let apiKey = '';
let attempts = 0;
const maxAttempts = 3;
while (!apiKey && attempts < maxAttempts) {
apiKey = await this.askSecureQuestion('Enter your Hugging Face token (hf_...): ');
if (!apiKey.trim()) {
console.log('Skipping Hugging Face token.');
return undefined;
}
// HuggingFace token accepted as-is, no format validation
break;
}
if (!apiKey) {
console.log('ā ļø Maximum attempts reached. Skipping HuggingFace configuration.');
return undefined;
}
console.log('ā
Hugging Face token configured! You can now generate images with better rate limits.');
return apiKey;
}
catch (error) {
console.error(`ā HuggingFace configuration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
return undefined;
}
}
getExistingHuggingFaceKey() {
try {
if ((0, fs_1.existsSync)(ENV_FILE_PATH)) {
const envContent = (0, fs_1.readFileSync)(ENV_FILE_PATH, 'utf8');
const match = envContent.match(/HUGGINGFACE_API_KEY=(.+)/);
return match ? match[1].trim() : null;
}
return null;
}
catch (error) {
console.warn(`ā ļø Could not read existing HuggingFace key: ${error instanceof Error ? error.message : 'Unknown error'}`);
return null;
}
}
categorizeModels(models) {
const categories = [
{
name: 'Recommended for Mock Generation',
description: 'Best models for generating realistic mock data',
models: [],
},
{
name: 'Fast & Economical',
description: 'Quick responses at lower cost',
models: [],
},
];
const recommendedIds = [
'anthropic/claude-3.5-sonnet',
'openai/gpt-4.1-nano',
'anthropic/claude-3-haiku',
];
const fastIds = ['openai/gpt-4.1-nano', 'anthropic/claude-3-haiku', 'openai/gpt-3.5-turbo'];
models.forEach(model => {
if (recommendedIds.includes(model.id)) {
categories[0].models.push(model);
}
else if (fastIds.includes(model.id)) {
categories[1].models.push(model);
}
});
return categories.filter(cat => cat.models.length > 0);
}
async askQuestion(prompt) {
try {
const answer = await this.rl.question(prompt);
return answer.trim();
}
catch (error) {
throw new Error(`Input error: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async askSecureQuestion(prompt) {
try {
// For sensitive inputs, we'll use a more secure approach
// Note: In a real implementation, you might want to use a library like 'read' for hidden input
console.log('š Secure input mode (input will be visible for now - consider using a secure input method)');
const answer = await this.rl.question(prompt);
return answer.trim();
}
catch (error) {
throw new Error(`Secure input error: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
validateInput(type, value) {
if (!value || !value.trim()) {
return false;
}
const pattern = VALIDATION_PATTERNS[type];
if (!pattern) {
// No pattern defined, accept any non-empty value
return true;
}
return pattern.test(value.trim());
}
async createBackupIfNeeded() {
try {
if ((0, fs_1.existsSync)(ENV_FILE_PATH)) {
console.log('š Creating backup of existing .env file...');
(0, fs_1.copyFileSync)(ENV_FILE_PATH, ENV_BACKUP_PATH);
console.log(`ā
Backup created: ${ENV_BACKUP_PATH}\\n`);
}
}
catch (error) {
console.warn(`ā ļø Could not create backup: ${error instanceof Error ? error.message : 'Unknown error'}`);
const proceed = await this.askQuestion('Continue without backup? (y/n) ');
if (proceed.toLowerCase() !== 'y' && proceed.toLowerCase() !== 'yes') {
throw new Error('User cancelled due to backup failure');
}
}
}
async restoreBackupIfNeeded() {
try {
if ((0, fs_1.existsSync)(ENV_BACKUP_PATH)) {
console.log('š Restoring backup due to configuration failure...');
(0, fs_1.copyFileSync)(ENV_BACKUP_PATH, ENV_FILE_PATH);
console.log('ā
Backup restored successfully');
}
}
catch (error) {
console.error(`ā Could not restore backup: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
getExistingApiKey() {
try {
if ((0, fs_1.existsSync)(ENV_FILE_PATH)) {
const envContent = (0, fs_1.readFileSync)(ENV_FILE_PATH, 'utf8');
const match = envContent.match(/OPENROUTER_API_KEY=(.+)/);
return match ? match[1].trim() : null;
}
return null;
}
catch (error) {
console.warn(`ā ļø Could not read existing .env file: ${error instanceof Error ? error.message : 'Unknown error'}`);
return null;
}
}
maskApiKey(key) {
if (key.length <= 8)
return '****';
return key.substring(0, 4) + '...' + key.substring(key.length - 4);
}
async configureImageProcessing() {
console.log('\\nStep 3: AI Image Processing Configuration (Optional)');
console.log('Configure AI image generation to replace placeholder images with real AI-generated images.\\n');
console.log('š This feature can automatically replace Picsum placeholder images in your mock data');
console.log(' with contextually appropriate AI-generated images using Hugging Face models.\\n');
const enableImages = await this.askQuestion('Do you want to enable AI image processing? (y/n) ');
if (enableImages.toLowerCase() !== 'y' && enableImages.toLowerCase() !== 'yes') {
console.log('ā
AI image processing disabled. Mock data will use placeholder images as-is.');
return {};
}
console.log('\\nšØ Configuring AI image processing...');
// Step 3a: Hugging Face API Key
const hfApiKey = await this.getHuggingFaceApiKey();
// Step 3b: Storage Configuration
const storageConfig = await this.configureStorage();
const config = {
HUGGINGFACE_API_KEY: hfApiKey,
...storageConfig,
};
if (hfApiKey || Object.keys(storageConfig).length > 0) {
console.log('\\nā
AI image processing configured successfully!');
console.log(' ⢠Images will be generated using AI models');
if (Object.keys(storageConfig).length > 0) {
console.log(' ⢠Generated images will be uploaded to cloud storage');
}
else {
console.log(' ⢠Generated images will be saved as base64 data URLs');
}
}
return config;
}
async configureStorage() {
console.log('\\nš¦ Cloud Storage Configuration (Optional)');
console.log('Configure cloud storage to upload generated images. Without storage,');
console.log('images will be embedded as base64 data URLs (larger file sizes).\\n');
const useStorage = await this.askQuestion('Do you want to configure cloud storage for images? (y/n) ');
if (useStorage.toLowerCase() !== 'y' && useStorage.toLowerCase() !== 'yes') {
console.log(' Skipping cloud storage. Images will be embedded as base64.');
return {};
}
console.log('\\nChoose your storage provider:');
console.log('1. AWS S3');
console.log('2. DigitalOcean Spaces');
const choice = await this.askQuestion('Select provider (1-2): ');
if (choice === '1') {
return this.configureAWS();
}
else if (choice === '2') {
return this.configureDigitalOcean();
}
else {
console.log('Invalid choice. Skipping storage configuration.');
return {};
}
}
async configureAWS() {
try {
console.log('\\nš¦ AWS S3 Configuration');
console.log('š Get AWS credentials from: \\x1b[36mhttps://console.aws.amazon.com/iam/home#/security_credentials\\x1b[0m');
console.log(' (Create an IAM user with S3 permissions)\\n');
let accessKeyId = '';
let attempts = 0;
const maxAttempts = 3;
while (!accessKeyId && attempts < maxAttempts) {
accessKeyId = await this.askSecureQuestion('AWS Access Key ID: ');
if (!accessKeyId.trim()) {
console.log('ā Access Key ID cannot be empty.');
attempts++;
continue;
}
// AWS Access Key accepted as-is, no format validation
break;
}
if (!accessKeyId)
return {};
let secretAccessKey = '';
attempts = 0;
while (!secretAccessKey && attempts < maxAttempts) {
secretAccessKey = await this.askSecureQuestion('AWS Secret Access Key: ');
if (!secretAccessKey.trim()) {
console.log('ā Secret Access Key cannot be empty.');
attempts++;
continue;
}
// AWS Secret Key accepted as-is, no format validation
break;
}
if (!secretAccessKey)
return {};
let region = (await this.askQuestion('AWS Region (default: us-east-1): ')) || 'us-east-1';
if (!this.validateInput('AWS_REGION', region)) {
console.log('ā ļø Invalid region format, using default: us-east-1');
region = 'us-east-1';
}
let bucketName = '';
attempts = 0;
while (!bucketName && attempts < maxAttempts) {
bucketName = await this.askQuestion('S3 Bucket Name: ');
if (!bucketName.trim()) {
console.log('ā Bucket name cannot be empty.');
attempts++;
continue;
}
// Bucket name accepted as-is, no format validation
break;
}
if (!bucketName)
return {};
const endpoint = await this.askQuestion('Custom S3 Endpoint (optional): ');
// Test AWS connection
console.log('\\nš Testing AWS S3 connection...');
try {
const { AWSS3Storage } = await Promise.resolve().then(() => __importStar(require('../services/aws-s3-storage')));
const s3 = new AWSS3Storage({
accessKeyId,
secretAccessKey,
region,
bucketName,
endpoint: endpoint || undefined,
});
const isConnected = await s3.testConnection();
if (isConnected) {
console.log('ā
AWS S3 connection successful!');
}
else {
console.log('ā ļø AWS S3 connection test failed, but configuration will be saved.');
}
}
catch (error) {
console.log(`ā ļø Could not test AWS S3 connection: ${error instanceof Error ? error.message : 'Unknown error'}`);
console.log('Configuration will be saved anyway.');
}
return {
STORAGE_PROVIDER: 'aws',
AWS_ACCESS_KEY_ID: accessKeyId,
AWS_SECRET_ACCESS_KEY: secretAccessKey,
AWS_REGION: region,
AWS_S3_BUCKET_NAME: bucketName,
AWS_S3_ENDPOINT: endpoint || undefined,
};
}
catch (error) {
console.error(`ā AWS configuration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
return {};
}
}
async configureDigitalOcean() {
console.log('\\nš DigitalOcean Spaces Configuration');
console.log('š Get Spaces credentials from: \\x1b[36mhttps://cloud.digitalocean.com/settings/api/tokens\\x1b[0m');
console.log(' (Go to Spaces Keys section)\\n');
// Show available regions
const { DigitalOceanSpaces } = await Promise.resolve().then(() => __importStar(require('../services/digitalocean-spaces')));
const regions = DigitalOceanSpaces.getAvailableRegions();
console.log('Available regions:');
regions.forEach((region, index) => {
console.log(` ${index + 1}. ${region.code} - ${region.name} (${region.location})`);
});
const regionChoice = await this.askQuestion(`\\nSelect region (1-${regions.length}): `);
const regionIndex = parseInt(regionChoice) - 1;
if (isNaN(regionIndex) || regionIndex < 0 || regionIndex >= regions.length) {
console.log('Invalid region choice. Using default: nyc3');
}
const selectedRegion = regions[regionIndex] || regions[0];
const accessKey = await this.askQuestion('Spaces Access Key: ');
if (!accessKey.trim())
return {};
const secretKey = await this.askQuestion('Spaces Secret Key: ');
if (!secretKey.trim())
return {};
// Ask if user wants to create a new Space or use existing one
const createNew = (await this.askQuestion('Create a new Space? (y/n, default: y): ')) || 'y';
let spaceName;
let spaceCreated = false;
if (createNew.toLowerCase() === 'y' || createNew.toLowerCase() === 'yes') {
spaceName = await this.askQuestion('New Space name (letters, numbers, hyphens only): ');
if (!spaceName.trim()) {
spaceName = `ai-images-${Date.now()}`;
console.log(`Using auto-generated name: ${spaceName}`);
}
// Create the Space
console.log(`\\nš Creating Space "${spaceName}" in ${selectedRegion.name}...`);
try {
const doSpaces = new DigitalOceanSpaces({
accessKeyId: accessKey,
secretAccessKey: secretKey,
region: selectedRegion.code,
spaceName,
});
await doSpaces.createSpace(spaceName, selectedRegion.code, true);
spaceCreated = true;
console.log('ā
Space created successfully!');
}
catch (error) {
console.log(`ā ļø Failed to create Space: ${error}`);
console.log('You can create it manually or use an existing one.');
}
}
else {
// List existing Spaces
console.log('\\nš Fetching existing Spaces...');
try {
const doSpaces = new DigitalOceanSpaces({
accessKeyId: accessKey,
secretAccessKey: secretKey,
region: selectedRegion.code,
});
const spaces = await doSpaces.listSpaces();
if (spaces.length === 0) {
console.log('No existing Spaces found. Please create one first.');
return {};
}
console.log('\\nExisting Spaces:');
spaces.forEach((space, index) => {
console.log(` ${index + 1}. ${space.name} (${space.region})`);
});
const spaceChoice = await this.askQuestion(`\\nSelect Space (1-${spaces.length}): `);
const spaceIndex = parseInt(spaceChoice) - 1;
if (isNaN(spaceIndex) || spaceIndex < 0 || spaceIndex >= spaces.length) {
console.log('Invalid Space choice.');
return {};
}
spaceName = spaces[spaceIndex].name;
}
catch (error) {
console.log(`ā ļø Could not list Spaces: ${error}`);
spaceName = await this.askQuestion('Enter Space name manually: ');
if (!spaceName.trim())
return {};
}
}
// Test connection
console.log('\\nš Testing DigitalOcean Spaces connection...');
try {
const doSpaces = new DigitalOceanSpaces({
accessKeyId: accessKey,
secretAccessKey: secretKey,
region: selectedRegion.code,
spaceName,
});
const isConnected = await doSpaces.testConnection();
if (isConnected) {
console.log('ā
DigitalOcean Spaces connection successful!');
console.log(`š” CDN URL: https://${spaceName}.${selectedRegion.code}.cdn.digitaloceanspaces.com`);
}
else {
console.log('ā ļø Connection test failed, but configuration will be saved.');
}
}
catch (error) {
console.log('ā ļø Could not test connection, but configuration will be saved.');
}
const doApiToken = await this.askQuestion('DigitalOcean API Token (optional, for advanced features): ');
return {
STORAGE_PROVIDER: 'digitalocean',
DO_SPACES_ACCESS_KEY: accessKey,
DO_SPACES_SECRET_KEY: secretKey,
DO_SPACES_REGION: selectedRegion.code,
DO_SPACES_NAME: spaceName,
DO_API_TOKEN: doApiToken || undefined,
};
}
async writeConfiguration(config) {
try {
const lines = [];
// Preserve existing non-AI related environment variables
if ((0, fs_1.existsSync)(ENV_FILE_PATH)) {
try {
const existing = (0, fs_1.readFileSync)(ENV_FILE_PATH, 'utf8');
const existingLines = existing.split('\\n');
existingLines.forEach(line => {
if (!line.startsWith('OPENROUTER_') &&
!line.startsWith('AWS_') &&
!line.startsWith('DO_') &&
!line.startsWith('HUGGINGFACE_') &&
!line.startsWith('STORAGE_PROVIDER')) {
lines.push(line);
}
});
}
catch (error) {
console.warn(`ā ļø Could not read existing .env file: ${error instanceof Error ? error.message : 'Unknown error'}`);
console.log('Creating new .env file...');
}
}
// Validate configuration before writing
if (!config.OPENROUTER_API_KEY) {
throw new Error('OpenRouter API key is required');
}
// OpenRouter configuration
lines.push(`OPENROUTER_API_KEY=${config.OPENROUTER_API_KEY.replace(/\n/g, '')}`);
if (config.OPENROUTER_DEFAULT_MODEL) {
lines.push(`OPENROUTER_DEFAULT_MODEL=${config.OPENROUTER_DEFAULT_MODEL.replace(/\n/g, '')}`);
}
if (config.OPENROUTER_MOCK_GENERATOR_MODEL) {
lines.push(`OPENROUTER_MOCK_GENERATOR_MODEL=${config.OPENROUTER_MOCK_GENERATOR_MODEL.replace(/\n/g, '')}`);
}
// Hugging Face configuration
if (config.HUGGINGFACE_API_KEY) {
lines.push(`HUGGINGFACE_API_KEY=${config.HUGGINGFACE_API_KEY.replace(/\n/g, '')}`);
}
// Storage provider
if (config.STORAGE_PROVIDER) {
lines.push(`STORAGE_PROVIDER=${config.STORAGE_PROVIDER}`);
}
// AWS configuration (if provided)
if (config.AWS_ACCESS_KEY_ID) {
lines.push(`AWS_ACCESS_KEY_ID=${config.AWS_ACCESS_KEY_ID.replace(/\n/g, '')}`);
}
if (config.AWS_SECRET_ACCESS_KEY) {
lines.push(`AWS_SECRET_ACCESS_KEY=${config.AWS_SECRET_ACCESS_KEY.replace(/\n/g, '')}`);
}
if (config.AWS_REGION) {
lines.push(`AWS_REGION=${config.AWS_REGION}`);
}
if (config.AWS_S3_BUCKET_NAME) {
lines.push(`AWS_S3_BUCKET_NAME=${config.AWS_S3_BUCKET_NAME}`);
}
if (config.AWS_S3_ENDPOINT) {
lines.push(`AWS_S3_ENDPOINT=${config.AWS_S3_ENDPOINT}`);
}
// DigitalOcean configuration (if provided)
if (config.DO_SPACES_ACCESS_KEY) {
lines.push(`DO_SPACES_ACCESS_KEY=${config.DO_SPACES_ACCESS_KEY.replace(/\n/g, '')}`);
}
if (config.DO_SPACES_SECRET_KEY) {
lines.push(`DO_SPACES_SECRET_KEY=${config.DO_SPACES_SECRET_KEY.replace(/\n/g, '')}`);
}
if (config.DO_SPACES_REGION) {
lines.push(`DO_SPACES_REGION=${config.DO_SPACES_REGION}`);
}
if (config.DO_SPACES_NAME) {
lines.push(`DO_SPACES_NAME=${config.DO_SPACES_NAME}`);
}
if (config.DO_API_TOKEN) {
lines.push(`DO_API_TOKEN=${config.DO_API_TOKEN.replace(/\n/g, '')}`);
}
// Write configuration with error handling
const content = lines.filter(line => line.trim()).join('\n') + '\n';
(0, fs_1.writeFileSync)(ENV_FILE_PATH, content, { mode: 0o600 }); // Secure file permissions
console.log(`š Configuration saved to: ${ENV_FILE_PATH}`);
// Clean up backup file on successful write
if ((0, fs_1.existsSync)(ENV_BACKUP_PATH)) {
try {
require('fs').unlinkSync(ENV_BACKUP_PATH);
}
catch (error) {
console.warn(`ā ļø Could not remove backup file: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
catch (error) {
throw new Error(`Failed to write configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
// Run the wizard
const wizard = new InitWizard();
wizard.run();
//# sourceMappingURL=init.js.map