UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

110 lines 3.52 kB
import inquirer from 'inquirer'; import { Firestore } from '@google-cloud/firestore'; import { logger, readCollectionMappings } from '../../../utils/index.js'; import { manageRequest } from './manageRequest.js'; import deploy from '../../deploy/index.js'; const EXPORT_ACTIONS = ['Backfill', 'Reset', 'Migrate']; const insertUntilDone = (projectId, collection, state) => { const { totalDocs, exported = 0, spinner } = state; return manageRequest(projectId, { collection, mode: 'insert', limit: 10000, startAfter: state.last }).then(async response => { if (!response.ok) { throw new Error(await response.text()); } return response.json(); }).then(({ result }) => { if (!result.success) { throw new Error(JSON.stringify(result)); } if (result.last) { spinner.succeed(`Exported ${result.exported + exported} / ${totalDocs} documents.`); const newSpinner = logger.spinner('Backfill in progress'); return insertUntilDone(projectId, collection, { totalDocs, spinner: newSpinner, last: result.last, exported: result.exported + exported }); } spinner.succeed('All documents have been exported.'); return 'DONE'; }); }; export const manageCollection = async (projectId, options) => { const collectionMap = readCollectionMappings(); const { collection } = options.collection ? { collection: options.collection } : await inquirer.prompt([{ type: 'select', name: 'collection', message: 'Which collection do you want to manage?', choices: Object.entries(collectionMap).map(([, entry]) => entry.collectionName) }]); const firestore = new Firestore({ projectId }); const totalDocs = await firestore.collection(collection).count().get().then(result => result.data().count).catch(() => { throw new Error('Collection does not exist!'); }); const { mode } = options.mode ? { mode: options.mode } : await inquirer.prompt([{ type: 'select', name: 'mode', message: `Which action do you want to perform on ${collection}?`, choices: EXPORT_ACTIONS }]); if (!(collection in collectionMap)) { spinner.fail(`Collection ${collection} is not initialized. Create the export for the collection first`); return; } switch (mode) { case 'Backfill': { const spinner = logger.spinner(`${mode} in progress`); return insertUntilDone(projectId, collectionMap[collection].sanitizedName, { totalDocs, spinner }).finally(() => spinner.stop()); } case 'Reset': case 'Migrate': { const doDeploy = options.allYes ?? (await inquirer.prompt([{ type: 'confirm', message: 'Would you like to deploy the cloud functions first? (this might be needed if you changed any config or schema)', name: 'doDeploy' }]).then(({ doDeploy }) => doDeploy)); if (doDeploy) { await deploy.functions(['atlasExport']); } const spinner = logger.spinner(`${mode} in progress`); return manageRequest(projectId, { collection: collectionMap[collection].sanitizedName, mode: mode.toLowerCase() }).then(() => { spinner.succeed(`${mode} completed successfully`); }).catch(error => { spinner.fail(`${mode} failed got: ${error.message}`); }); } default: spinner.fail('Unknown mode'); } };