Source: hubspot/hubdb/hubdb.js

/** @module hubspot/fetchdb */
/// <reference path="../../types/types.js" />
import { downloadHubDbTable, createHubDbTable, updateHubDbTable, clearHubDbTableRows, addRowsToHubDbTable } from '@hubspot/local-dev-lib/hubdb'
import { fetchRows } from '@hubspot/local-dev-lib/api/hubdb'
import http from '@hubspot/local-dev-lib/http'
import chalk from 'chalk'
import * as ui from '../../utils/ui.js'
import { getThemeOptions } from '../../utils/options.js'
import { selectTables, selectFiles, confirmTableOverwrite } from './prompts.js'
import ora, { oraPromise } from 'ora'
import { getFileList } from '../../utils/fs.js'
import { createRequire } from 'module'
import { throwErrorIfMissingScope } from '../auth/scopes.js'
const require = createRequire(import.meta.url)
const cmslibOptions = getThemeOptions()

const HUBDB_API_PATH = 'cms/v3/hubdb'

/**
 * #### fetch HubDB tables
 * @async
 * @private
 * @param {number} accountId - hubspot account id
 * @returns {Promise<any>} hubdb tables
 */
async function fetchTables (accountId) {
  // @ts-ignore
  return http.default.get(accountId, {
    url: `${HUBDB_API_PATH}/tables`
  })
}

/**
 * #### fetch HubDB tables
 * @async
 * @param {HUBSPOT_AUTH_CONFIG} config - hubspot authentication config
 * @returns undefined
 */
async function fetchHubDb (config) {
  try {
    const timeStart = ui.startTask('fetchDb')
    const dest = `${process.cwd()}/${cmslibOptions.hubdbFolder}`
    const accountId = config.portals[0].portalId
    throwErrorIfMissingScope(config, 'hubdb')
    // fetch all tables from the account
    const tables = await fetchTables(accountId)
    // select tables to download
    const selectedTables = await selectTables(tables.results)
    const msg = (/** @type {string} */ tableName) => `Saving HubDB ${chalk.magenta(tableName)} table into ${chalk.dim.green(`${tableName}.json`)} file`
    for await (const table of selectedTables) {
      // download each table into a json file
      await oraPromise(downloadHubDbTable(accountId, table.id, `${dest}/${table.name}.json`), { text: msg(table.name) })
    }
    ui.endTask({ taskName: 'fetchDb', timeStart })
  } catch (error) {
    console.error(error)
    process.exit(1)
  }
}

/**
 * #### upload HubDB tables
 * @async
 * @param {HUBSPOT_AUTH_CONFIG} config - hubspot authentication config
 * @returns undefined
 */
async function uploadHubDb (config) {
  try {
    const timeStart = ui.startTask('uploadDb')
    const hubdbFolder = `${process.cwd()}/${cmslibOptions.hubdbFolder}`
    const accountId = config.portals[0].portalId
    throwErrorIfMissingScope(config, 'hubdb')
    // get all json files from the hubdb folder
    const files = await getFileList(`${hubdbFolder}/*.json`, { objectMode: true })
    if (files === undefined || files.length === 0) {
      console.log('No HubDb files found')
      process.exit(0)
    }
    // select files to upload
    const selectedFiles = await selectFiles(files)
    // fetch all tables from the account
    const tables = await fetchTables(accountId)
    const createMsg = (/** @type {string} */ fileName) => `Creating and publishing ${chalk.magenta(fileName)} table based on ${chalk.dim.green(`${fileName}.json`)} file`
    const overwriteMsg = (/** @type {string} */ fileName) => `Overwriting and publishing ${chalk.magenta(fileName)} table.`
    for (const file of selectedFiles) {
      // check if table already exists
      const table = tables.results.find((/** @type {any} */ t) => t.name === file.label)
      if (table) {
        console.warn(`${chalk.red('[Warning]')} ${chalk.magenta(file.label)} table already exists in the selected account.`)
        const confirm = await confirmTableOverwrite(file.label)
        if (confirm) {
          const spinner = ora(overwriteMsg(file.label)).start()
          try {
            // get table rows from the json file
            const rows = require(file.path).rows
            // update table columns and options
            await updateHubDbTable(accountId, table.id, file.path)
            // check if remote table has rows
            const remoteRows = await fetchRows(accountId, table.id)
            if (remoteRows.results.length) {
              // clear remote table rows if exists
              await clearHubDbTableRows(accountId, table.id)
            }
            // add new rows to the table from the json file
            await addRowsToHubDbTable(accountId, table.id, rows)
            spinner.succeed()
          } catch (error) {
            spinner.fail()
            console.error(error)
            process.exit(1)
          }
        }
      } else {
        // create and publish table if it does not exist
        await oraPromise(createHubDbTable(accountId, file.path), { text: createMsg(file.label) })
      }
    }
    ui.endTask({ taskName: 'uploadDb', timeStart })
  } catch (error) {
    console.error(error)
    process.exit(1)
  }
}

export { fetchHubDb, uploadHubDb }

Table of contents