@papavault/cli
Version:
CLI tool for Papa Vault Secret Manager
139 lines (138 loc) • 6.41 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCredentialsCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const config_1 = require("../utils/config");
const api_1 = require("../utils/api");
function parseContent(content, fileName, format) {
// If format is specified as json, try to parse as JSON
if (format === 'json') {
try {
// First try to parse as JSON
return JSON.parse(content);
}
catch {
// If not JSON, try to parse as key-value format
const envVars = {};
content.split('\n').forEach(line => {
// Skip empty lines and comments
if (!line || line.startsWith('#'))
return;
// Split by first = and trim
const [key, ...valueParts] = line.split('=');
const trimmedKey = key?.trim();
// Skip if key is empty
if (!trimmedKey)
return;
const value = valueParts.join('=').trim();
// Remove quotes if present
envVars[trimmedKey] = value.replace(/^["']|["']$/g, '');
});
return envVars;
}
}
// Return original content if no parsing needed or parsing failed
return content;
}
async function getCredentials(projectId, stage, files, format, token) {
try {
// First, get the project to validate it exists
const project = await (0, api_1.getProject)(projectId, token);
const environment = project.environments.find(env => env.id === stage);
if (!environment) {
throw new Error(`Environment ${stage} not found in project ${project.name}`);
}
// Get all credential files for the project and environment
const allCredentialFiles = await (0, api_1.getCredentialFiles)(projectId, stage, token);
// If no files specified, return all credentials
if (!files || files.length === 0) {
const credentials = [];
for (const file of allCredentialFiles) {
try {
const { downloadUrl } = await (0, api_1.getCredentialFile)(projectId, stage, file.id, token);
const content = await (0, api_1.downloadCredentialFile)(downloadUrl, token);
credentials.push({
fileName: file.fileName,
content: parseContent(content, file.fileName, format)
});
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to get credentials for ${file.fileName}: ${error.message}`);
}
throw error;
}
}
return credentials;
}
// Filter the files that were requested
const requestedFiles = allCredentialFiles.filter(file => files.includes(file.fileName));
if (requestedFiles.length === 0) {
throw new Error(`No matching credential files found. Available files: ${allCredentialFiles.map(f => f.fileName).join(', ')}`);
}
const credentials = [];
// For each requested file, get its content
for (const file of requestedFiles) {
try {
// Get the credential file details
const { downloadUrl } = await (0, api_1.getCredentialFile)(projectId, stage, file.id, token);
// Download the file content
const content = await (0, api_1.downloadCredentialFile)(downloadUrl, token);
credentials.push({
fileName: file.fileName,
content: parseContent(content, file.fileName, format)
});
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to get credentials for ${file.fileName}: ${error.message}`);
}
throw error;
}
}
return credentials;
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to get credentials: ${error.message}`);
}
throw error;
}
}
const getCredentialsCommand = (program) => {
program
.command('get-credentials')
.description('Get credentials from specified files for a project and stage')
.requiredOption('--project-id <projectId>', 'Project ID')
.requiredOption('--stage <stage>', 'Stage (e.g., dev, prod)')
.option('--files <files>', 'Comma-separated list of file names (optional, returns all credentials if not provided)')
.option('--format <format>', 'Output format (optional, currently supports "json" to parse content as JSON)')
.option('-t, --token <token>', 'API token for authentication (overrides stored token)')
.action(async (options) => {
// Check if authenticated
if (!(0, config_1.isAuthenticated)() && !options.token) {
console.log(chalk_1.default.red('You need to be logged in to get credentials.'));
console.log(chalk_1.default.yellow('Run `papavault login` to authenticate or provide a token with --token.'));
return;
}
const { projectId, stage, files, format, token } = options;
const fileList = files ? files.split(',').map((file) => file.trim()) : undefined;
const spinner = (0, ora_1.default)('Fetching credentials...').start();
try {
const credentials = await getCredentials(projectId, stage, fileList, format, token);
spinner.succeed('Credentials retrieved successfully!');
// Output credentials in JSON format
console.log(JSON.stringify(credentials, null, 2));
}
catch (error) {
spinner.fail('Failed to retrieve credentials');
console.error(chalk_1.default.red('\nError:'), error instanceof Error ? error.message : 'Unknown error occurred');
process.exit(1);
}
});
};
exports.getCredentialsCommand = getCredentialsCommand;