UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

146 lines 7.61 kB
import { SfError } from '@salesforce/core'; import c from 'chalk'; import fs from 'fs-extra'; import * as path from 'path'; import { elapseEnd, elapseStart, execCommand, uxLog } from './index.js'; import { getConfig } from '../../config/index.js'; import { prompts } from './prompts.js'; import { isProductionOrg } from './orgUtils.js'; export const dataFolderRoot = path.join('.', 'scripts', 'data'); // Import data from sfdmu folder export async function importData(sfdmuPath, commandThis, options = {}) { const dtl = await getDataWorkspaceDetail(sfdmuPath); if (dtl?.isDelete === true) { throw new SfError('Your export.json contains deletion info, please use appropriate delete command'); } uxLog(commandThis, c.cyan(`Importing data from ${c.green(dtl?.full_label)} ...`)); /* jscpd:ignore-start */ uxLog(commandThis, c.italic(c.grey(dtl?.description))); const targetUsername = options.targetUsername || commandThis.org.getConnection().username; await fs.ensureDir(path.join(sfdmuPath, 'logs')); const config = await getConfig('branch'); const dataImportCommand = 'sf sfdmu:run' + ` --sourceusername csvfile` + ` --targetusername ${targetUsername}` + // Keep targetusername until sfdmu switches to target-org ` -p ${sfdmuPath}` + ' --noprompt' + // Needed for production orgs (config.sfdmuCanModify || process.env.SFDMU_CAN_MODIFY ? ` --canmodify ${config.sfdmuCanModify || process.env.SFDMU_CAN_MODIFY}` : ''); /* jscpd:ignore-end */ elapseStart(`import ${dtl?.full_label}`); await execCommand(dataImportCommand, commandThis, { fail: true, output: true, }); elapseEnd(`import ${dtl?.full_label}`); } // Delete data using sfdmu folder export async function deleteData(sfdmuPath, commandThis, options = {}) { const config = await getConfig('branch'); const dtl = await getDataWorkspaceDetail(sfdmuPath); if (dtl?.isDelete === false) { throw new SfError('Your export.json does not contain deletion information. Please check http://help.sfdmu.com/full-documentation/advanced-features/delete-from-source'); } // If org is production, make sure that "runnableInProduction": true is present in export.json const isProdOrg = await isProductionOrg(options?.targetUsername || options?.conn?.username || "ERROR", options); if (isProdOrg === true && (dtl?.runnableInProduction || false) !== true) { throw new SfError(`To run this delete SFDMU script in production, you need to define "runnableInProduction": true in its export.json file`); } if (isProdOrg === true && !config.sfdmuCanModify) { uxLog(this, c.yellow(`If you see a sfdmu error, you probably need to add a property sfdmuCanModify: YOUR_ORG_INSTANCE_URL in the related config/branches/.sfdx-hardis.YOUR_BRANCH.yml config file.`)); } // Delete using sfdmu uxLog(commandThis, c.cyan(`Deleting data from ${c.green(dtl?.full_label)} ...`)); uxLog(commandThis, c.italic(c.grey(dtl?.description))); const targetUsername = options.targetUsername || options.conn.username; await fs.ensureDir(path.join(sfdmuPath, 'logs')); const dataImportCommand = 'sf sfdmu:run' + ` --sourceusername ${targetUsername}` + ` -p ${sfdmuPath}` + ' --noprompt' + (config.sfdmuCanModify ? ` --canmodify ${config.sfdmuCanModify}` : ''); elapseStart(`delete ${dtl?.full_label}`); await execCommand(dataImportCommand, commandThis, { fail: true, output: true, }); elapseEnd(`delete ${dtl?.full_label}`); } // Export data from sfdmu folder export async function exportData(sfdmuPath, commandThis, options = {}) { /* jscpd:ignore-start */ const dtl = await getDataWorkspaceDetail(sfdmuPath); if (dtl?.isDelete === true) { throw new SfError('Your export.json contains deletion info, please use appropriate delete command'); } /* jscpd:ignore-end */ uxLog(commandThis, c.cyan(`Exporting data from ${c.green(dtl?.full_label)} ...`)); uxLog(commandThis, c.italic(c.grey(dtl?.description))); const sourceUsername = options.sourceUsername || commandThis.org.getConnection().username; await fs.ensureDir(path.join(sfdmuPath, 'logs')); const dataImportCommand = `sf sfdmu:run --sourceusername ${sourceUsername} --targetusername csvfile -p ${sfdmuPath} --noprompt`; // keep target username until sfdmu migrates to SF cli base await execCommand(dataImportCommand, commandThis, { fail: true, output: true, }); } export async function selectDataWorkspace(opts = { selectDataLabel: 'Please select a data workspace to export' }) { if (!fs.existsSync(dataFolderRoot)) { throw new SfError("There is no sfdmu root folder 'scripts/data' in your workspace. Create it and define sfdmu exports using sfdmu: https://help.sfdmu.com/"); } const sfdmuFolders = fs .readdirSync(dataFolderRoot, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => path.join('.', 'scripts', 'data', dirent.name)); if (sfdmuFolders.length === 0) { throw new SfError('There is no sfdmu folder in your workspace. Create them using sfdmu: https://help.sfdmu.com/'); } const choices = []; for (const sfdmuFolder of sfdmuFolders) { const dtl = await getDataWorkspaceDetail(sfdmuFolder); if (dtl !== null) { choices.push({ title: `📁 ${dtl.full_label}`, description: dtl.description, value: sfdmuFolder, }); } } const sfdmuDirResult = await prompts({ type: 'select', name: 'value', message: c.cyanBright(opts.selectDataLabel), choices: choices, }); return sfdmuDirResult.value; } export async function getDataWorkspaceDetail(dataWorkspace) { const exportFile = path.join(dataWorkspace, 'export.json'); if (!fs.existsSync(exportFile)) { uxLog(this, c.yellow(`Your SFDMU folder ${c.bold(dataWorkspace)} must contain an ${c.bold('export.json')} configuration file`)); return null; } const exportFileJson = JSON.parse(await fs.readFile(exportFile, 'utf8')); const folderName = (dataWorkspace.replace(/\\/g, '/').match(/([^/]*)\/*$/) || [])[1]; const hardisLabel = exportFileJson.sfdxHardisLabel || folderName; const hardisDescription = exportFileJson.sfdxHardisDescription || dataWorkspace; return { full_label: `[${folderName}]${folderName != hardisLabel ? `: ${hardisLabel}` : ''}`, label: hardisLabel, description: hardisDescription, exportJson: exportFileJson, isDelete: isDeleteDataWorkspace(exportFileJson), runnableInProduction: exportFileJson.runnableInProduction || false }; } // Checks if a sfdmu data workspace can delete object!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*!*!é!*é!!!é*!é!*!*é!*!*!*!*!*!*!**!!!!!!!*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!s -> https://help.sfdmu.com/full-documentation/advanced-features/delete-from-source export function isDeleteDataWorkspace(exportFileJson) { let isDelete = false; for (const objectConfig of exportFileJson.objects) { if (objectConfig?.deleteFromSource === true || objectConfig.operation === 'DeleteSource') { isDelete = true; } } return isDelete; } //# sourceMappingURL=dataUtils.js.map