UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

138 lines (136 loc) 5.17 kB
import path from 'path'; import fs from 'fs'; import inquirer from 'inquirer'; import { exec, logger, sanitizeCollection, writeCollectionMapping } from '../../../utils/index.js'; import { manageRequest } from './manageRequest.js'; import deploy from '../../deploy/index.js'; const onWriteTemplate = collection => { const sanitizedName = sanitizeCollection(collection); return `\ import { functions, bigquery } from '@limebooth/atlas-cloud-functions'; import * as collections from '../collections/index.js'; export default functions.firestore .document('${collection}/{docId}') .onWrite(async event => bigquery.insertDocumentOnWrite(collections['${sanitizedName}'], event)); `; }; export const initializeCollection = async (projectId, options) => { const { collection } = options.collection ? { collection: options.collection } : await inquirer.prompt([{ type: 'input', name: 'collection', message: 'Give the collection path to export:' }]); const spinner = logger.spinner(`Initializing collection \`${collection}\`...`); const { results } = await manageRequest(projectId, { collection, mode: 'config' }).then(response => response.json()); if (!results?.config) { throw new Error('No configuration returned from cloud function.'); } const { config } = results; const sanitizedName = sanitizeCollection(collection); const collectionsDir = path.join(process.cwd(), 'functions', 'atlas-export', 'src', 'collections'); if (!fs.existsSync(collectionsDir)) { fs.mkdirSync(collectionsDir, { recursive: true }); } const formattedConfig = JSON.stringify(config, null, 4); const collectionFilePath = path.join(collectionsDir, `${sanitizedName}.js`); const configContent = ` /* eslint-disable quote-props */ /* eslint-disable quotes */ // Auto-generated configuration for ${collection} export default ${formattedConfig}; `; fs.writeFileSync(collectionFilePath, configContent); const indexFilePath = path.join(collectionsDir, 'index.js'); let indexContent = fs.readFileSync(indexFilePath, 'utf-8'); if (!indexContent.includes(`export { default as ${sanitizedName} }`)) { indexContent += `export { default as ${sanitizedName} } from './${sanitizedName}.js';\n`; } fs.writeFileSync(indexFilePath, indexContent); const syncDir = path.join(process.cwd(), 'functions', 'atlas-export', 'src', 'sync'); if (!fs.existsSync(syncDir)) { fs.mkdirSync(syncDir, { recursive: true }); } const syncFilePath = path.join(syncDir, `${sanitizedName}.js`); const syncContent = onWriteTemplate(collection); fs.writeFileSync(syncFilePath, syncContent); const syncIndexFilePath = path.join(syncDir, 'index.js'); let syncIndexContent = fs.readFileSync(syncIndexFilePath, 'utf-8'); if (!syncIndexContent.includes(`export { default as ${sanitizedName} }`)) { syncIndexContent += `export { default as ${sanitizedName} } from './${sanitizedName}.js';\n`; } fs.writeFileSync(syncIndexFilePath, syncIndexContent); writeCollectionMapping(sanitizedName, collection); spinner.succeed(`Collection \`${collection}\` initialized successfully.\n`); logger.info(`Configuration saved to: ${collectionFilePath}`); logger.info(`Sync function saved to: ${syncFilePath}\n`); logger.info('It is recommend to check the newly generated configuration and validate the schema.'); const openEditor = options.allYes ? false : await inquirer.prompt([{ type: 'confirm', name: 'openEditor', message: 'Would you like to open the configuration in your editor?' }]).then(({ openEditor }) => openEditor); if (openEditor) { const subCmd = exec(`${process.env.EDITOR || 'code'} ${collectionFilePath}`, {}); await new Promise(resolve => { subCmd.on('error', error => { logger.error(error); resolve(); }); subCmd.on('exit', resolve); }); } const doDeploy = options.allYes ?? (await inquirer.prompt([{ type: 'confirm', name: 'doDeploy', message: 'Continue with deploying to Firebase functions?' }]).then(({ doDeploy }) => doDeploy)); if (doDeploy) { return deploy.functions(['atlasExport'], { codebase: 'atlas-export', projectId }); } const { createTable } = await inquirer.prompt([{ type: 'confirm', name: 'createTable', message: 'Would you like to create the BigQuery table now (runs manage function in reset mode)?', default: true }]); if (createTable) { const tableSpinner = logger.spinner(`Creating BigQuery table for collection \`${collection}\`...`); const response = await manageRequest(projectId, { collection, mode: 'reset' }); const result = await response.json(); if (response.ok) { tableSpinner.succeed(`BigQuery table created successfully for collection \`${collection}\`.`); logger.info('Table is now ready to receive data from Firestore.'); } else { tableSpinner.fail(`Failed to create BigQuery table: ${result.error || 'Unknown error'}`); throw new Error(result.error || 'Failed to create BigQuery table'); } } return Promise.resolve(); };