UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

97 lines 2.93 kB
import { randomBytes } from 'node:crypto'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { getRequiredFirebasercProjects } from '../../utils/firebase.js'; import { logger } from '../../utils/logger.js'; import { createSecret } from '../../utils/secrets.js'; const SECRET_DEFINITIONS = [{ key: 'puls-atlas-api-key', value: randomBytesImpl => createSecretValue(16, { randomBytesImpl }) }, { key: 'puls-atlas-jwt', value: randomBytesImpl => createSecretValue(32, { randomBytesImpl }) }, { key: 'puls-gcr-auth-token', value: randomBytesImpl => createSecretValue(32, { randomBytesImpl }) }]; const isSecretAlreadyExistsError = (error, secretName) => error instanceof Error && error.message === `Secret ${secretName} already exists`; export const createSecretValue = (length = 32, dependencies = {}) => { const { randomBytesImpl = randomBytes } = dependencies; return randomBytesImpl(Math.ceil(length / 2)).toString('hex').slice(0, length); }; export const confirmCreateSecret = async ({ createSecretImpl = createSecret, loggerImpl = logger, projectId, promptImpl = inquirer.prompt, secretName, secretValue }) => { const { shouldCreate } = await promptImpl([{ type: 'confirm', name: 'shouldCreate', default: false, message: `Do you want to create the secret ${chalk.yellow(secretName)} ` + `for project ${chalk.yellow(projectId)}?` }]); if (!shouldCreate) { return 'skipped'; } const spinner = loggerImpl.spinner(`Creating secret ${secretName}...`); try { await createSecretImpl(secretName, secretValue, projectId); spinner.succeed(`Secret ${secretName} created successfully.`); return 'created'; } catch (error) { if (isSecretAlreadyExistsError(error, secretName)) { spinner.succeed(`Secret ${secretName} already exists.`); return 'existing'; } spinner.fail(`Failed to create secret ${secretName}: ${error.message}`); throw error; } }; export default async (dependencies = {}) => { const { createSecret: createSecretImpl = createSecret, getRequiredFirebasercProjects: getRequiredFirebasercProjectsImpl = getRequiredFirebasercProjects, logger: loggerImpl = logger, prompt: promptImpl = inquirer.prompt, randomBytes: randomBytesImpl = randomBytes } = dependencies; const { developmentProjectId, productionProjectId } = getRequiredFirebasercProjectsImpl(); for (const { key, value } of SECRET_DEFINITIONS) { await confirmCreateSecret({ createSecretImpl, loggerImpl, projectId: productionProjectId, promptImpl, secretName: key, secretValue: value(randomBytesImpl) }); await confirmCreateSecret({ createSecretImpl, loggerImpl, projectId: developmentProjectId, promptImpl, secretName: key, secretValue: value(randomBytesImpl) }); } return true; };