UNPKG

@dxatscale/sfprofiles

Version:
113 lines (99 loc) 4.96 kB
import { Connection, Org, SfdxProject } from '@salesforce/core'; import { Sfpowerkit } from '@utils/sfpowerkit'; import SFPLogger, {LoggerLevel } from '@dxatscale/sfp-logger'; import { parentPort, workerData } from 'worker_threads'; import * as fs from 'fs-extra'; import * as path from 'path'; import * as xml2js from 'xml2js'; import * as util from 'util'; import ProfileWriter from '@impl/metadata/writer/profileWriter'; import Profile from '@impl/metadata/schema'; import ProfileComponentReconciler from './profileComponentReconciler'; import { MetadataResolver, SourceComponent } from '@salesforce/source-deploy-retrieve'; import { ProfileSourceFile } from './profileActions'; import _ from 'lodash'; export default class ReconcileWorker { conn: Connection; public constructor(private targetOrg: string, private isSourceOnly: boolean) {} public async reconcile(profilesToReconcile: ProfileSourceFile[], destFolder: string) { //Init Cache for each worker thread from file system Sfpowerkit.initCache(); if (this.targetOrg) { const org = await Org.create({ aliasOrUsername: this.targetOrg }); this.conn = org.getConnection(); } else { //Load all local components from source to database await this.loadAllLocalComponents(); } let result: string[] = []; for (let count = 0; count < profilesToReconcile.length; count++) { let reconciledProfile = await this.reconcileProfileJob(profilesToReconcile[count], destFolder); result.push(reconciledProfile[0]); } return result; } private async loadAllLocalComponents() { const resolver = new MetadataResolver(); const project = await SfdxProject.resolve(); let packageDirectories = project.getPackageDirectories(); for (const packageDirectory of packageDirectories) { const components = resolver.getComponentsFromPath(packageDirectory.path); for (const component of components) { this.loadComponentsTocache(component); } } } private loadComponentsTocache(component:SourceComponent){ Sfpowerkit.addToCache(`SOURCE_${component.type.name}_${component.fullName}`, true); Sfpowerkit.addToCache(`${component.type.name}_SOURCE_CACHE_AVAILABLE`, true); let children:SourceComponent[] = component.getChildren(); for (const child of children) { this.loadComponentsTocache(child); } } public reconcileProfileJob(profileComponent: ProfileSourceFile, destFolder: string): Promise<string[]> { // eslint-disable-next-line @typescript-eslint/no-unused-vars let reconcilePromise = new Promise<string[]>((resolve, reject) => { let result: string[] = []; // Handle result of command execution let profileXmlString = fs.readFileSync(profileComponent.path); const parser = new xml2js.Parser({ explicitArray: true }); const parseString = util.promisify(parser.parseString) as _.Function1<xml2js.convertableToString, Promise<{ Profile: Profile }>>; parseString(profileXmlString) .then((parseResult) => { let profileWriter = new ProfileWriter(); const profileObj: Profile = profileWriter.toProfile(parseResult.Profile); // as Profile return profileObj; }) .then((profileObj) => { return new ProfileComponentReconciler(this.conn, this.isSourceOnly).reconcileProfileComponents( profileObj, profileComponent.name ); }) .then((profileObj) => { //write profile back let outputFile = profileComponent.path; if (destFolder != null) { outputFile = path.join(destFolder, path.basename(profileComponent.path)); } let profileWriter = new ProfileWriter(); profileWriter.writeProfile(profileObj, outputFile); result.push(outputFile); resolve(result); return result; }) .catch((error) => { SFPLogger.log( 'Error while processing file ' + profileComponent + '. ERROR Message: ' + error.message, LoggerLevel.ERROR ); }); }); return reconcilePromise; } } Sfpowerkit.setLogLevel(workerData.loglevel, workerData.isJsonFormatEnabled); let reconcileWorker = new ReconcileWorker(workerData.targetOrg, workerData.isSourceOnly); reconcileWorker.reconcile(workerData.profileChunk, workerData.destFolder).then((result) => { parentPort.postMessage(result); })