auto-translatr
Version:
An automatic translation library
146 lines (145 loc) ⢠7.21 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import * as fs from 'fs';
import * as path from 'path';
import * as readline from 'readline';
import { left, right } from './utils';
const SETTINGS_FILE = 'auto-translatr.settings.json';
// Helper function to validate and fix settings
const validateAndFixSettings = (settings) => {
// Check if default language is in supported array
if (!settings.supported.includes(settings.default)) {
console.warn(`ā ļø Default language '${settings.default}' not found in supported languages. Adding it automatically.`);
return Object.assign(Object.assign({}, settings), { supported: [settings.default, ...settings.supported] });
}
return settings;
};
// Helper function to get the default settings
export const getDefaultSettings = () => ({
default: 'en',
supported: ['en', 'fr', 'de'],
output: 'i18n',
include: ['.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte'],
ignore: ['node_modules', '.git', 'dist', 'build', '.next', 'coverage'],
openai: {
model: 'gpt-4o-mini',
apiKey: process.env.OPENAI_API_KEY || ''
}
});
// Helper function to read settings from file
export const readSettingsFile = () => {
try {
const settingsPath = path.join(process.cwd(), SETTINGS_FILE);
if (!fs.existsSync(settingsPath)) {
return left(new Error(`Settings file ${SETTINGS_FILE} not found`));
}
const fileContent = fs.readFileSync(settingsPath, 'utf-8');
const rawSettings = JSON.parse(fileContent);
// Validate required fields
if (!rawSettings.default) {
return left(new Error('Settings file is missing required field: default'));
}
if (!rawSettings.supported || !Array.isArray(rawSettings.supported) || rawSettings.supported.length === 0) {
return left(new Error('Settings file is missing required field: supported (must be a non-empty array)'));
}
if (!rawSettings.openai || !rawSettings.openai.model) {
return left(new Error('Settings file is missing required field: openai.model. Please set your OpenAI model in the file or as OPENAI_MODEL environment variable.'));
}
// Set defaults for new optional fields if missing
if (!rawSettings.output) {
rawSettings.output = 'i18n';
}
if (!rawSettings.include || !Array.isArray(rawSettings.include)) {
rawSettings.include = ['.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte'];
}
if (!rawSettings.ignore || !Array.isArray(rawSettings.ignore)) {
rawSettings.ignore = ['node_modules', '.git', 'dist', 'build', '.next', 'coverage'];
}
// Merge with environment variables for API key if not provided
if (rawSettings.openai && !rawSettings.openai.apiKey && process.env.OPENAI_API_KEY) {
rawSettings.openai.apiKey = process.env.OPENAI_API_KEY;
}
if (!rawSettings.openai || !rawSettings.openai.apiKey) {
return left(new Error('Settings file is missing required field: openai.apiKey. Please set your OpenAI API key in the file or as OPENAI_API_KEY environment variable.'));
}
// Validate and fix settings (ensure default is in supported array)
const validatedSettings = validateAndFixSettings(rawSettings);
return right(validatedSettings);
}
catch (error) {
return left(error);
}
};
// Helper function to prompt user input
const promptUser = (question) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise((resolve) => {
rl.question(question, (answer) => {
rl.close();
resolve(answer.trim().toLowerCase());
});
});
};
// Helper function to create default settings file
export const createDefaultSettingsFile = () => __awaiter(void 0, void 0, void 0, function* () {
try {
const settingsPath = path.join(process.cwd(), SETTINGS_FILE);
const defaultSettings = getDefaultSettings();
// Don't include the API key in the file for security
const settingsToWrite = Object.assign(Object.assign({}, defaultSettings), { openai: Object.assign(Object.assign({}, defaultSettings.openai), { apiKey: '' }) });
const fileContent = JSON.stringify(settingsToWrite, null, 2);
fs.writeFileSync(settingsPath, fileContent, 'utf-8');
console.log(`š Created ${SETTINGS_FILE} with default settings`);
if (!process.env.OPENAI_API_KEY)
return left(new Error('Settings file is missing required field: openai.apiKey. Please set your OpenAI API key in the file or as OPENAI_API_KEY environment variable.'));
else
defaultSettings.openai.apiKey = process.env.OPENAI_API_KEY;
// Ask user about default languages
console.log(`\nš Default supported languages: ${defaultSettings.supported.join(', ')}`);
const userResponse = yield promptUser('Do you want to use these default languages? (Y/N): ');
if (userResponse === 'n' || userResponse === 'no') {
console.log(`\nš Please edit the 'supported' property in ${SETTINGS_FILE} to include your desired languages, then run the command again.`);
process.exit(0);
}
else if (userResponse === 'y' || userResponse === 'yes') {
console.log('ā
Using default languages. Continuing...');
}
else {
console.log('ā Invalid response. Please edit the settings file manually if needed.');
process.exit(0);
}
return right(defaultSettings);
}
catch (error) {
return left(error);
}
});
// Helper function to initialize settings (creates defaults if none exist)
export const initializeSettings = () => __awaiter(void 0, void 0, void 0, function* () {
const readResult = readSettingsFile();
if (readResult.type === 'left') {
console.log(`āļø ${readResult.value.message}, creating default settings...`);
return yield createDefaultSettingsFile();
}
console.log(`āļø Loaded settings from ${SETTINGS_FILE}`);
return readResult;
});
// Helper function to load or create settings
export const loadSettings = () => {
const readResult = readSettingsFile();
if (readResult.type === 'left') {
return readResult; // Return the error immediately, don't create defaults
}
console.log(`āļø Loaded settings from ${SETTINGS_FILE}`);
return readResult;
};