UNPKG

csv2gsheets

Version:

CLI tool to convert local CSV files into Google Sheets files in a designated Google Drive folder.

145 lines 6.73 kB
// convert command import fs from 'fs'; import { google } from 'googleapis'; import open from 'open'; import path from 'path'; import { authorize, isAuthorized } from '../auth.js'; import { C2gError } from '../c2g-error.js'; import { CONFIG_FILE_NAME, CONFIG_KEYS, } from '../constants.js'; import { MESSAGES } from '../messages.js'; import * as utils from '../utils.js'; /** * Convert the contents of the config object * to a human-readable message string. * @param config The config object * @returns The human-readable message string */ export function config2message(config) { return Object.keys(config) .map((key) => `${CONFIG_KEYS[key]}: ${config[key]}`) .join('\n '); } /** * The main function of the convert command. * @param options The options passed to the convert command */ export default async function convert(options) { if (!isAuthorized()) { // If the user is NOT logged in, exit the program with an error message throw new C2gError(MESSAGES.error.c2gErrorNotLoggedIn); } // If configFilePath is not specified in the options, use the CONFIG_FILE_NAME in the current working directory const configFilePath = options.configFilePath ? options.configFilePath : path.join(process.cwd(), CONFIG_FILE_NAME); // Read the configuration file and validate its contents const config = utils.validateConfig(utils.readConfigFileSync(configFilePath)); // Show message on the console let convertingCsvWithFollowingSettings = MESSAGES.log.convertingCsvWithFollowingSettings(config2message(config)); convertingCsvWithFollowingSettings = options.dryRun ? `${MESSAGES.log.runningOnDryRun}\n\n${convertingCsvWithFollowingSettings}` : convertingCsvWithFollowingSettings; console.info(convertingCsvWithFollowingSettings); // Get the full paths of the local CSV files in the source directory const csvFiles = utils.getLocalCsvFilePaths(config.sourceDir); if (csvFiles.length === 0) { // If there are no CSV files, exit the program with a message throw new C2gError(MESSAGES.error.c2gErrorNoCsvFilesFound); } // Authorize the user const auth = await authorize(); const drive = google.drive({ version: 'v3', auth }); // Get the file names of all Google Sheets files in the target Google Drive folder const existingSheetsFiles = await utils.getExistingSheetsFiles(drive, config); // Create an array of objects containing the file name, full path, // and Google Sheets file ID with the same file name (if it exists) // for the respective CSV files const csvFilesObjArray = csvFiles.map((csvFile) => { const basename = path.basename(csvFile); const fileName = basename.replace(/\.(csv)$/i, ''); return { name: fileName, basename: basename, path: csvFile, existingSheetsFileId: config.updateExistingGoogleSheets ? utils.getExistingSheetsFileId(fileName, existingSheetsFiles) : null, }; }); // Get the Google Drive folder ID of the "csv" folder in the target Google Drive folder // If the "csv" folder does not exist, create it. // If config.saveOriginalFilesToDrive is false, csvFolderId will be null const csvFolderId = await utils.getCsvFolderId(drive, config); if (csvFolderId) { console.info(MESSAGES.log.uploadingOriginalCsvFilesTo(csvFolderId)); } for (const csvFileObj of csvFilesObjArray) { // Show the name of the CSV file being processed, // and whether it will update an existing Google Sheets file or create a new one console.info(MESSAGES.log.processingCsvFile(csvFileObj.basename, csvFileObj.existingSheetsFileId)); // The actual conversion of the CSV file into a Google Sheets file if (!options.dryRun) { // First, read the CSV file const csvData = fs.createReadStream(csvFileObj.path); // Depending on the value of config.updateExistingGoogleSheets, // either update an existing Google Sheets file or create a new one. // Create a new Google Sheets file anyway if csvFileObj.existingSheetsFileId is null. if (config.updateExistingGoogleSheets && csvFileObj.existingSheetsFileId) { // Update an existing Google Sheets file await drive.files.update({ supportsAllDrives: config.targetIsSharedDrive, fileId: csvFileObj.existingSheetsFileId, media: { mimeType: 'text/csv', body: csvData, }, }); } else { // Create a new Google Sheets file const requestBody = { name: csvFileObj.name, mimeType: 'application/vnd.google-apps.spreadsheet', }; if (!utils.isRoot(config.targetDriveFolderId)) { requestBody.parents = [config.targetDriveFolderId]; } await drive.files.create({ supportsAllDrives: config.targetIsSharedDrive, requestBody: requestBody, media: { mimeType: 'text/csv', body: csvData, }, }); } if (config.saveOriginalFilesToDrive && csvFolderId) { // Upload the CSV file to the "csv" folder await drive.files.create({ supportsAllDrives: config.targetIsSharedDrive, requestBody: { name: csvFileObj.basename, mimeType: 'text/csv', parents: [csvFolderId], }, media: { mimeType: 'text/csv', body: fs.createReadStream(csvFileObj.path), }, }); } } // Show complete message for this file on the console console.info(MESSAGES.log.processingCsvFileComplete); } if (options.browse) { // Open the target Google Drive folder in the default browser if the --browse option is specified const url = utils.isRoot(config.targetDriveFolderId) ? 'https://drive.google.com/drive/my-drive' : `https://drive.google.com/drive/folders/${config.targetDriveFolderId}`; console.info(MESSAGES.log.openingTargetDriveFolderOnBrowser(url)); await open(url); } } //# sourceMappingURL=convert.js.map