UNPKG

@flxbl-io/sfp

Version:

sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model

210 lines 22.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PackageCreationParams = void 0; const ApexTypeFetcher_1 = __importDefault(require("../apex/parser/ApexTypeFetcher")); const ProjectConfig_1 = __importDefault(require("../project/ProjectConfig")); const SfpPackageContentGenerator_1 = __importDefault(require("./generators/SfpPackageContentGenerator")); const SourceToMDAPIConvertor_1 = __importDefault(require("./packageFormatConvertors/SourceToMDAPIConvertor")); const PackageManifest_1 = __importDefault(require("./components/PackageManifest")); const MetadataCount_1 = __importDefault(require("./components/MetadataCount")); const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const fs = __importStar(require("fs-extra")); const path_1 = __importDefault(require("path")); const SfpPackage_1 = __importStar(require("./SfpPackage")); const AssignPermissionSetFetcher_1 = __importDefault(require("./propertyFetchers/AssignPermissionSetFetcher")); const DestructiveManifestPathFetcher_1 = __importDefault(require("./propertyFetchers/DestructiveManifestPathFetcher")); const ReconcileProfilePropertyFetcher_1 = __importDefault(require("./propertyFetchers/ReconcileProfilePropertyFetcher")); const CreateUnlockedPackageImpl_1 = __importDefault(require("./packageCreators/CreateUnlockedPackageImpl")); const CreateSourcePackageImpl_1 = __importDefault(require("./packageCreators/CreateSourcePackageImpl")); const CreateDataPackageImpl_1 = __importDefault(require("./packageCreators/CreateDataPackageImpl")); const lodash = require("lodash"); const PackageVersionUpdater_1 = __importDefault(require("./version/PackageVersionUpdater")); const AnalyzerRegistry_1 = require("./analyser/AnalyzerRegistry"); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const CreateDiffPackageImpl_1 = __importDefault(require("./packageCreators/CreateDiffPackageImpl")); const sfp_logger_2 = require("@flxbl-io/sfp-logger"); class SfpPackageBuilder { static async buildPackageFromProjectDirectory(logger, projectDirectory, sfdx_package, params, packageCreationParams, projectConfig) { if (!projectConfig) { projectConfig = ProjectConfig_1.default.getSFDXProjectConfig(projectDirectory); } else { // Clone the projectConfig to prevent mutation projectConfig = lodash.cloneDeep(projectConfig); } let propertyFetchers = [ new AssignPermissionSetFetcher_1.default(), new DestructiveManifestPathFetcher_1.default(), new ReconcileProfilePropertyFetcher_1.default(), ]; let startTime = Date.now; let sfpPackage = new SfpPackage_1.default(); sfpPackage.package_name = sfdx_package; sfpPackage.projectConfig = projectConfig; sfpPackage.apiVersion = sfpPackage.projectConfig.sourceApiVersion; sfpPackage.packageDescriptor = ProjectConfig_1.default.getPackageDescriptorFromConfig(sfdx_package, sfpPackage.projectConfig); sfpPackage.projectDirectory = projectDirectory ? projectDirectory : ''; sfpPackage.packageDirectory = sfpPackage.packageDescriptor.path; //Set Default Version Number sfpPackage.versionNumber = sfpPackage.packageDescriptor.versionNumber; //set additional options sfpPackage.sourceVersion = params?.sourceVersion; sfpPackage.branch = params?.branch; sfpPackage.repository_url = params?.repositoryUrl; if (params?.configFilePath == null) sfpPackage.configFilePath = 'config/project-scratch-def.json'; else sfpPackage.configFilePath = params?.configFilePath; for (const propertyFetcher of propertyFetchers) { await propertyFetcher.getsfpProperties(sfpPackage, logger); } //Get Package Type sfpPackage.package_type = ProjectConfig_1.default.getPackageType(projectConfig, sfdx_package); sfpPackage = SfpPackageBuilder.handleVersionNumber(params, sfpPackage, packageCreationParams); // Requires destructiveChangesPath which is set by the property fetcher sfpPackage.workingDirectory = await SfpPackageContentGenerator_1.default.generateSfpPackageDirectory(logger, sfpPackage.projectDirectory, sfpPackage.projectConfig, sfpPackage.packageName, sfpPackage.packageDescriptor.path, sfpPackage.versionNumber, sfpPackage.destructiveChangesPath, sfpPackage.configFilePath, params?.pathToReplacementForceIgnore); sfpPackage.resolvedPackageDirectory = path_1.default.join(sfpPackage.workingDirectory, sfpPackage.packageDescriptor.path); //Don't proceed further if packageType is Data if (sfpPackage.package_type != SfpPackage_1.PackageType.Data) { let sourceToMdapiConvertor = new SourceToMDAPIConvertor_1.default(sfpPackage.workingDirectory, sfpPackage.packageDescriptor.path, ProjectConfig_1.default.getSFDXProjectConfig(sfpPackage.workingDirectory).sourceApiVersion, logger); sfpPackage.mdapiDir = (await sourceToMdapiConvertor.convert()).packagePath; const packageManifest = await PackageManifest_1.default.create(sfpPackage.mdapiDir); sfpPackage.payload = packageManifest.manifestJson; sfpPackage.triggers = packageManifest.fetchTriggers(); sfpPackage.isApexFound = packageManifest.isApexInPackage(); sfpPackage.isProfilesFound = packageManifest.isProfilesInPackage(); sfpPackage.isPermissionSetGroupFound = packageManifest.isPermissionSetGroupsFoundInPackage(); sfpPackage.isPayLoadContainTypesSupportedByProfiles = packageManifest.isPayLoadContainTypesSupportedByProfiles(); let apexFetcher = new ApexTypeFetcher_1.default(sfpPackage.resolvedPackageDirectory); sfpPackage.apexClassesSortedByTypes = apexFetcher.getClassesClassifiedByType(); sfpPackage.apexTestClassses = apexFetcher.getTestClasses(); sfpPackage.metadataCount = await MetadataCount_1.default.getMetadataCount(sfpPackage.workingDirectory, sfpPackage.packageDescriptor.path); sfpPackage.apexClassWithOutTestClasses = apexFetcher.getClassesOnlyExcludingTestsAndInterfaces(); sfpPackage.isTriggerAllTests = this.isAllTestsToBeTriggered(sfpPackage, logger); //Load component Set let componentSet = source_deploy_retrieve_1.ComponentSet.fromSource(path_1.default.resolve(sfpPackage.workingDirectory, sfpPackage.projectDirectory, sfpPackage.packageDirectory)); //Run through all analyzers let analyzers = AnalyzerRegistry_1.AnalyzerRegistry.getAnalyzers(); for (const analyzer of analyzers) { if (analyzer.isEnabled(sfpPackage, logger)) sfpPackage = await analyzer.analyze(sfpPackage, componentSet, logger); } } //Create the actual package let createPackage; if (!packageCreationParams) packageCreationParams = { breakBuildIfEmpty: true }; let packageType = sfpPackage.package_type; if (params?.overridePackageTypeWith) packageType = params?.overridePackageTypeWith.toLocaleLowerCase(); //Get Implementors switch (packageType) { case SfpPackage_1.PackageType.Unlocked: createPackage = new CreateUnlockedPackageImpl_1.default(sfpPackage.workingDirectory, sfpPackage, packageCreationParams, logger, params); break; case SfpPackage_1.PackageType.Source: createPackage = new CreateSourcePackageImpl_1.default(sfpPackage.workingDirectory, sfpPackage, packageCreationParams, logger, params); break; case SfpPackage_1.PackageType.Data: createPackage = new CreateDataPackageImpl_1.default(sfpPackage.workingDirectory, sfpPackage, packageCreationParams, logger, params); break; case SfpPackage_1.PackageType.Diff: packageCreationParams.revisionFrom = params.revisionFrom; packageCreationParams.revisionTo = params.revisionTo; createPackage = new CreateDiffPackageImpl_1.default(sfpPackage.workingDirectory, sfpPackage, packageCreationParams, logger, params); break; } return createPackage.exec(); } /* * Handle version Numbers of package * If VersionNumber is explcitly passed, use that * else allow autosubstitute using buildNumber for Source and Data if available */ static handleVersionNumber(params, sfpPackage, packageCreationParams) { if (params?.packageVersionNumber) { sfpPackage.versionNumber = params.packageVersionNumber; } else if (packageCreationParams?.buildNumber) { if (sfpPackage.packageType != SfpPackage_1.PackageType.Unlocked) { let versionUpdater = new PackageVersionUpdater_1.default(); sfpPackage.versionNumber = versionUpdater.substituteBuildNumber(sfpPackage, packageCreationParams.buildNumber); } } else { sfpPackage.versionNumber = sfpPackage.packageDescriptor.versionNumber; } return sfpPackage; } static async buildPackageFromArtifact(artifact, logger) { //Read artifact metadata let sfpPackage = new SfpPackage_1.default(); Object.assign(sfpPackage, fs.readJSONSync(artifact.packageMetadataFilePath, { encoding: 'utf8' })); sfpPackage.sourceDir = artifact.sourceDirectoryPath; sfpPackage.changelogFilePath = artifact.changelogFilePath; sfpPackage.projectConfig = ProjectConfig_1.default.getSFDXProjectConfig(artifact.sourceDirectoryPath); sfpPackage.packageDescriptor = ProjectConfig_1.default.getSFDXPackageDescriptor(artifact.sourceDirectoryPath, sfpPackage.package_name); sfpPackage.projectDirectory = artifact.sourceDirectoryPath; sfpPackage.packageDirectory = sfpPackage.packageDescriptor.path; sfpPackage.isTriggerAllTests = this.isAllTestsToBeTriggered(sfpPackage, logger); return sfpPackage; } static isAllTestsToBeTriggered(sfpPackage, logger) { if (this.isOptimizedDeploymentForSourcePackage(sfpPackage) == false || (sfpPackage.packageType == SfpPackage_1.PackageType.Source && sfpPackage.isApexFound == true && sfpPackage.apexTestClassses == null)) { sfp_logger_1.default.printHeaderLine('WARNING! NON OPTIMAL DEPLOYMENT', sfp_logger_2.COLOR_WARNING, sfp_logger_1.LoggerLevel.INFO, logger); sfp_logger_1.default.log(`This package has apex classes/triggers, In order to deploy optimally, each class need to have a minimum` + `75% test coverage,We are unable to find any test classes in the given package, hence will be deploying` + `via triggering all local tests,This definitely is not optimal approach on large orgs` + `Please consider adding test classes for the classes in the package`, sfp_logger_1.LoggerLevel.INFO, logger); sfp_logger_1.default.printHeaderLine('', sfp_logger_2.COLOR_WARNING, sfp_logger_1.LoggerLevel.INFO, logger); return true; } else return false; } // Allow individual packages to use non optimized path static isOptimizedDeploymentForSourcePackage(pkgDescriptor) { if (pkgDescriptor['isOptimizedDeployment'] == null) return true; else return pkgDescriptor['isOptimizedDeployment']; } } exports.default = SfpPackageBuilder; // Options while creating package class PackageCreationParams { constructor() { this.breakBuildIfEmpty = true; } } exports.PackageCreationParams = PackageCreationParams; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2ZwUGFja2FnZUJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9wYWNrYWdlL1NmcFBhY2thZ2VCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEscUZBQW1GO0FBQ25GLDZFQUFxRDtBQUNyRCx5R0FBaUY7QUFDakYsOEdBQXNGO0FBQ3RGLG1GQUEyRDtBQUMzRCwrRUFBdUQ7QUFDdkQsbUVBQXNFO0FBQ3RFLDZDQUErQjtBQUMvQixnREFBd0I7QUFFeEIsMkRBQThGO0FBRTlGLCtHQUF1RjtBQUN2Rix1SEFBK0Y7QUFDL0YseUhBQTBGO0FBQzFGLDRHQUFvRjtBQUNwRix3R0FBZ0Y7QUFDaEYsb0dBQTRFO0FBQzVFLGlDQUFrQztBQUVsQyw0RkFBb0U7QUFDcEUsa0VBQStEO0FBQy9ELCtFQUFrRTtBQUNsRSxvR0FBMkU7QUFDM0UscURBQXFEO0FBRXJELE1BQXFCLGlCQUFpQjtJQUMzQixNQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxDQUNoRCxNQUFjLEVBQ2QsZ0JBQXdCLEVBQ3hCLFlBQW9CLEVBQ3BCLE1BQXlCLEVBQ3pCLHFCQUE2QyxFQUM3QyxhQUFtQjtRQUVuQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDakIsYUFBYSxHQUFHLHVCQUFhLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN6RSxDQUFDO2FBQU0sQ0FBQztZQUNKLDhDQUE4QztZQUM5QyxhQUFhLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBRUQsSUFBSSxnQkFBZ0IsR0FBc0I7WUFDdEMsSUFBSSxvQ0FBMEIsRUFBRTtZQUNoQyxJQUFJLHdDQUE4QixFQUFFO1lBQ3BDLElBQUkseUNBQXdCLEVBQUU7U0FDakMsQ0FBQztRQUVGLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFH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