UNPKG

sf-decomposer

Version:

Break down large Salesforce metadata files into smaller, more manageable files for version control and then recreate deployment-compatible files.

114 lines 5.57 kB
'use strict'; /* eslint-disable no-await-in-loop */ import { resolve, relative, join } from 'node:path'; import { readdir, stat, rm, rename } from 'node:fs/promises'; import { DisassembleXMLFileHandler, setLogLevel } from 'xml-disassembler'; import { CUSTOM_LABELS_FILE, WORKFLOW_SUFFIX_MAPPING } from '../../helpers/constants.js'; import { moveFiles } from '../core/moveFiles.js'; import { handleNestedLoyaltyProgramSetupDecomposition } from './lps/loyaltyProgramSetup.js'; import { handleNestedPermissionSetDecomposition } from './perm-set/permSets.js'; export async function decomposeFileHandler(metaAttributes, prepurge, postpurge, debug, format, ignorePath, strategy, decomposeNestedPerms) { const { metadataPaths, metaSuffix, strictDirectoryName, folderType, uniqueIdElements } = metaAttributes; if (debug) setLogLevel('debug'); for (const metadataPath of metadataPaths) { if (strictDirectoryName || folderType) { await subDirectoryHandler(metadataPath, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms); } else if (metaSuffix === 'labels') { // do not use the prePurge flag in the xml-disassembler package for labels due to file moving if (prepurge) await prePurgeLabels(metadataPath); const absoluteLabelFilePath = resolve(metadataPath, CUSTOM_LABELS_FILE); const relativeLabelFilePath = relative(process.cwd(), absoluteLabelFilePath); await disassembleHandler(relativeLabelFilePath, uniqueIdElements, false, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms); // move labels from the directory they are created in await moveAndRenameLabels(metadataPath); } else { await disassembleHandler(metadataPath, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms); } if (metaSuffix === 'workflow') { await renameWorkflows(metadataPath); } } } async function disassembleHandler(filePath, uniqueIdElements, prePurge, postPurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms) { const handler = new DisassembleXMLFileHandler(); let decomposeFormat; let decomposePostPurge; const decomposePermSets = decomposeNestedPerms && metaSuffix === 'permissionset' && strategy === 'grouped-by-tag'; const decomposeLoyalyProgram = metaSuffix === 'loyaltyProgramSetup' && strategy === 'unique-id'; if (decomposePermSets || decomposeLoyalyProgram) { decomposeFormat = 'xml'; decomposePostPurge = false; } else { decomposeFormat = format; decomposePostPurge = postPurge; } await handler.disassemble({ filePath, uniqueIdElements, prePurge, postPurge: decomposePostPurge, ignorePath, format: decomposeFormat, strategy, }); // Dispatch recursive decomposition based on type if (decomposePermSets) { await handleNestedPermissionSetDecomposition(filePath, uniqueIdElements, handler, format); } if (decomposeLoyalyProgram) { await handleNestedLoyaltyProgramSetupDecomposition(filePath, handler, format); } } async function prePurgeLabels(metadataPath) { const subFiles = await readdir(metadataPath); for (const subFile of subFiles) { const subfilePath = join(metadataPath, subFile); if ((await stat(subfilePath)).isFile() && subFile !== CUSTOM_LABELS_FILE) { await rm(subfilePath, { recursive: true }); } } } async function moveAndRenameLabels(metadataPath) { const sourceDirectory = join(metadataPath, 'CustomLabels', 'labels'); const destinationDirectory = metadataPath; const labelFiles = await readdir(sourceDirectory); for (const file of labelFiles) { if (file.includes('.labels-meta')) { const oldFilePath = join(sourceDirectory, file); const newFileName = file.replace('.labels-meta', '.label-meta'); const newFilePath = join(destinationDirectory, newFileName); await rename(oldFilePath, newFilePath); } } await moveFiles(sourceDirectory, destinationDirectory, () => true); await rm(join(metadataPath, 'CustomLabels'), { recursive: true }); } async function subDirectoryHandler(metadataPath, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms) { const subFiles = await readdir(metadataPath); for (const subFile of subFiles) { const subFilePath = join(metadataPath, subFile); if ((await stat(subFilePath)).isDirectory()) { await disassembleHandler(subFilePath, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms); } } } async function renameWorkflows(directory) { const files = await readdir(directory, { recursive: true }); for (const file of files) { // Check if the file matches any suffix in WORKFLOW_SUFFIX_MAPPING for (const [suffix, newSuffix] of Object.entries(WORKFLOW_SUFFIX_MAPPING)) { if (file.includes(suffix)) { const oldFilePath = join(directory, file); const newFilePath = join(directory, file.replace(suffix, newSuffix)); await rename(oldFilePath, newFilePath); break; } } } } //# sourceMappingURL=decomposeFileHandler.js.map