UNPKG

envx-cli

Version:

Environment file encryption and management tool

282 lines 13.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCreateCommand = void 0; const chalk_1 = __importDefault(require("chalk")); const commander_1 = require("commander"); const path_1 = __importDefault(require("path")); const schemas_1 = require("../schemas"); const exec_1 = require("../utils/exec"); const file_1 = require("../utils/file"); const interactive_1 = require("../utils/interactive"); const createCreateCommand = () => { const command = new commander_1.Command('create'); command .description('Create new environment files') .option('-e, --environment <env>', 'Environment name (e.g., development, staging, production)') .option('-t, --template <path>', 'Template file path to use as base') .option('-c, --cwd <path>', 'Working directory path') .option('-i, --interactive', 'Interactive mode for creating multiple environments') .option('--overwrite', 'Overwrite existing files without confirmation') .action(async (options) => { try { await executeCreate(options); } catch (error) { exec_1.CliUtils.error(`File creation failed: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } }); return command; }; exports.createCreateCommand = createCreateCommand; async function executeCreate(rawOptions) { exec_1.CliUtils.header('Environment File Creation'); const cwd = rawOptions.cwd || exec_1.ExecUtils.getCurrentDir(); const existingEnvironments = await file_1.FileUtils.findAllEnvironments(cwd); if (existingEnvironments.length > 0) { exec_1.CliUtils.info(`Existing environments: ${existingEnvironments.map(env => exec_1.CliUtils.formatEnvironment(env)).join(', ')}`); } let environment = rawOptions.environment; let template = rawOptions.template; if (rawOptions.interactive) { await executeInteractiveCreate(cwd, existingEnvironments, template, rawOptions.overwrite); return; } if (!environment) { environment = await interactive_1.InteractiveUtils.promptEnvironmentName('Enter environment name:'); } if (!file_1.FileUtils.isValidEnvironmentName(environment)) { throw new Error('Environment name can only contain letters, numbers, hyphens, and underscores'); } (0, schemas_1.validateCreateOptions)({ environment, template, cwd, overwrite: rawOptions.overwrite, }); if (existingEnvironments.includes(environment)) { exec_1.CliUtils.warning(`Environment '${environment}' already exists`); const envFiles = await file_1.FileUtils.findEnvFiles(environment, cwd); if (envFiles.length > 0) { console.log('Existing files:'); envFiles.forEach(file => { const displayPath = file.encrypted ? file_1.FileUtils.getEncryptedPath(file.path) : file.path; console.log(` • ${exec_1.CliUtils.formatPath(displayPath, cwd)}`); }); if (!rawOptions.overwrite) { const confirm = await interactive_1.InteractiveUtils.confirmOperation('Do you want to create additional files for this environment?', false); if (!confirm) { exec_1.CliUtils.info('Operation cancelled.'); return; } } } } if (template) { const templatePath = path_1.default.isAbsolute(template) ? template : path_1.default.join(cwd, template); if (!(await file_1.FileUtils.fileExists(templatePath))) { throw new Error(`Template file not found: ${template}`); } template = templatePath; } const envFilePath = path_1.default.join(cwd, `.env.${environment}`); const relativePath = file_1.FileUtils.getRelativePath(envFilePath, cwd); if ((await file_1.FileUtils.fileExists(envFilePath)) && !rawOptions.overwrite) { const confirm = await interactive_1.InteractiveUtils.confirmOperation(`File ${chalk_1.default.cyan(relativePath)} already exists. Overwrite?`, false); if (!confirm) { exec_1.CliUtils.info('Operation cancelled.'); return; } } exec_1.CliUtils.info(`Creating environment file: ${chalk_1.default.cyan(relativePath)}`); try { const result = await file_1.FileUtils.createEnvTemplate(envFilePath, template); if (result.success) { exec_1.CliUtils.success(`Created: ${chalk_1.default.cyan(relativePath)}`); console.log(); exec_1.CliUtils.info('Next steps:'); console.log(chalk_1.default.gray(`• Edit ${relativePath} and add your environment variables`)); console.log(chalk_1.default.gray(`• Use "envx encrypt -e ${environment}" to encrypt the file`)); console.log(chalk_1.default.gray('• Add the encrypted .gpg file to version control')); } else { exec_1.CliUtils.error(result.message); if (result.error) { console.log(chalk_1.default.red(` • ${result.error.message}`)); } } } catch (error) { exec_1.CliUtils.error(`Failed to create file: ${error instanceof Error ? error.message : String(error)}`); } } async function executeInteractiveCreate(cwd, existingEnvironments, template, overwrite) { exec_1.CliUtils.subheader('Interactive Environment Creation'); const commonEnvironments = [ 'development', 'staging', 'production', 'local', 'test', ]; const suggestedEnvironments = commonEnvironments.filter(env => !existingEnvironments.includes(env)); if (suggestedEnvironments.length > 0) { exec_1.CliUtils.info('Suggested environments:'); suggestedEnvironments.forEach(env => { console.log(` • ${exec_1.CliUtils.formatEnvironment(env)}`); }); console.log(); } const { createMode } = (await interactive_1.InteractiveUtils.confirmOperation('Do you want to select from suggested environments?')) ? { createMode: 'suggested' } : { createMode: 'custom' }; let environmentsToCreate = []; if (createMode === 'suggested' && suggestedEnvironments.length > 0) { environmentsToCreate = await interactive_1.InteractiveUtils.selectMultipleEnvironments(suggestedEnvironments, 'Select environments to create:'); } const { addCustom } = (await interactive_1.InteractiveUtils.confirmOperation('Do you want to add custom environments?', createMode === 'custom')) ? { addCustom: true } : { addCustom: false }; if (addCustom) { let addingMore = true; while (addingMore) { const newEnv = await interactive_1.InteractiveUtils.promptEnvironmentName('Enter environment name:'); if (!environmentsToCreate.includes(newEnv) && !existingEnvironments.includes(newEnv)) { environmentsToCreate.push(newEnv); exec_1.CliUtils.success(`Added ${exec_1.CliUtils.formatEnvironment(newEnv)} to creation list`); } else if (existingEnvironments.includes(newEnv)) { exec_1.CliUtils.warning(`Environment ${exec_1.CliUtils.formatEnvironment(newEnv)} already exists`); const confirm = await interactive_1.InteractiveUtils.confirmOperation('Do you want to create files for this environment anyway?'); if (confirm) { environmentsToCreate.push(newEnv); } } else { exec_1.CliUtils.warning(`Environment ${exec_1.CliUtils.formatEnvironment(newEnv)} already in creation list`); } const { continueAdding } = (await interactive_1.InteractiveUtils.confirmOperation('Do you want to add another environment?', false)) ? { continueAdding: true } : { continueAdding: false }; addingMore = continueAdding; } } if (environmentsToCreate.length === 0) { exec_1.CliUtils.warning('No environments selected for creation.'); return; } if (!template) { const { useTemplate } = (await interactive_1.InteractiveUtils.confirmOperation('Do you want to use a template file?', false)) ? { useTemplate: true } : { useTemplate: false }; if (useTemplate) { const commonTemplates = ['.env.example', '.env.template', '.env.sample']; const foundTemplates = []; for (const templateName of commonTemplates) { const templatePath = path_1.default.join(cwd, templateName); if (await file_1.FileUtils.fileExists(templatePath)) { foundTemplates.push(templateName); } } if (foundTemplates.length > 0) { const { templateChoice } = (await interactive_1.InteractiveUtils.selectFiles([...foundTemplates, 'Enter custom path'], 'Select template file:')); if (templateChoice === 'Enter custom path') { const { customTemplate } = (await interactive_1.InteractiveUtils.promptEnvironmentName('Enter template file path:')); template = customTemplate; } else { template = path_1.default.join(cwd, templateChoice[0]); } } else { const { customTemplate } = (await interactive_1.InteractiveUtils.promptEnvironmentName('Enter template file path:')); template = customTemplate; } if (template) { const templatePath = path_1.default.isAbsolute(template) ? template : path_1.default.join(cwd, template); if (!(await file_1.FileUtils.fileExists(templatePath))) { exec_1.CliUtils.warning(`Template file not found: ${template}`); template = undefined; } else { template = templatePath; exec_1.CliUtils.success(`Using template: ${exec_1.CliUtils.formatPath(template, cwd)}`); } } } } console.log(); exec_1.CliUtils.subheader('Creation Summary'); console.log(`Will create ${environmentsToCreate.length} environment file(s):`); environmentsToCreate.forEach(env => { console.log(` • .env.${exec_1.CliUtils.formatEnvironment(env)}`); }); if (template) { console.log(`Using template: ${exec_1.CliUtils.formatPath(template, cwd)}`); } const confirm = await interactive_1.InteractiveUtils.confirmOperation('Create these environment files?'); if (!confirm) { exec_1.CliUtils.info('Operation cancelled.'); return; } exec_1.CliUtils.subheader('Creating Files'); let successCount = 0; let errorCount = 0; for (const environment of environmentsToCreate.sort()) { const envFilePath = path_1.default.join(cwd, `.env.${environment}`); const relativePath = file_1.FileUtils.getRelativePath(envFilePath, cwd); console.log(); exec_1.CliUtils.info(`Creating: ${chalk_1.default.cyan(relativePath)}`); try { if ((await file_1.FileUtils.fileExists(envFilePath)) && !overwrite) { const fileConfirm = await interactive_1.InteractiveUtils.confirmOperation(`File already exists. Overwrite ${relativePath}?`, false); if (!fileConfirm) { exec_1.CliUtils.warning('Skipped existing file'); continue; } } const result = await file_1.FileUtils.createEnvTemplate(envFilePath, template); if (result.success) { exec_1.CliUtils.success(`Created: ${chalk_1.default.cyan(relativePath)}`); successCount++; } else { exec_1.CliUtils.error(`Failed: ${result.message}`); errorCount++; } } catch (error) { exec_1.CliUtils.error(`Error creating ${relativePath}: ${error instanceof Error ? error.message : String(error)}`); errorCount++; } } console.log(); exec_1.CliUtils.subheader('Creation Results'); if (successCount > 0) { exec_1.CliUtils.success(`Successfully created ${successCount} file(s)`); } if (errorCount > 0) { exec_1.CliUtils.error(`Failed to create ${errorCount} file(s)`); } if (successCount > 0) { console.log(); exec_1.CliUtils.info('Next steps:'); console.log(chalk_1.default.gray('• Edit the created files and add your environment variables')); console.log(chalk_1.default.gray('• Use "envx encrypt" to encrypt sensitive files')); console.log(chalk_1.default.gray('• Use "envx interactive" to set up .envrc with secrets')); } if (errorCount > 0) { process.exit(1); } } //# sourceMappingURL=create.js.map