sf-package-combiner
Version:
Merge multiple Salesforce package.xml manifests into a single file for Salesforce CLI deployments.
71 lines • 3.06 kB
JavaScript
import { ComponentSet } from '@salesforce/source-deploy-retrieve';
import { sfXmlns } from '../utils/constants.js';
import { getConcurrencyThreshold } from '../utils/getConcurrencyThreshold.js';
import { mapLimit } from '../utils/mapLimit.js';
import { determineApiVersion } from './determineApiVersion.js';
import { writePackage } from './writePackage.js';
export async function mergePackageXmlFiles(files, combinedPackage, userApiVersion, noApiVersion) {
const warnings = [];
const apiVersions = [];
const concurrencyLimit = getConcurrencyThreshold();
const combinedSet = new ComponentSet();
if (files) {
await mapLimit(files, concurrencyLimit, async (filePath) => {
try {
const componentSet = await ComponentSet.fromManifest({ manifestPath: filePath });
if (componentSet.size === 0) {
warnings.push(`Invalid or empty package.xml: ${filePath}`);
return;
}
for (const component of componentSet.toArray()) {
combinedSet.add(component);
}
const version = componentSet.sourceApiVersion;
// Stryker disable next-line ConditionalExpression,LogicalOperator -- null/undefined version doesn't affect max computation in determineApiVersion
if (version && !apiVersions.includes(version)) {
apiVersions.push(version);
}
}
catch (err) {
const sdrMessage = err instanceof Error ? err.message : String(err);
warnings.push(`Invalid or empty package.xml: ${filePath}. [SDR] ${sdrMessage}`);
}
});
}
const metadataTypes = groupComponentsByType(combinedSet.toArray());
const version = determineApiVersion(apiVersions, userApiVersion, noApiVersion);
const packageContents = {
Package: {
'@_xmlns': sfXmlns,
types: Array.from(metadataTypes.entries())
.map(([name, members]) => ({
members: Array.from(new Set(members)).sort((a, b) => a.localeCompare(b)),
name,
}))
.sort(sortTypesWithCustomObjectFirst),
version,
},
};
await writePackage(packageContents, combinedPackage);
return warnings;
}
export const CUSTOM_OBJECT_TYPE = 'CustomObject';
export function sortTypesWithCustomObjectFirst(a, b) {
if (a.name === CUSTOM_OBJECT_TYPE && b.name !== CUSTOM_OBJECT_TYPE)
return -1;
if (a.name !== CUSTOM_OBJECT_TYPE && b.name === CUSTOM_OBJECT_TYPE)
return 1;
return a.name.localeCompare(b.name);
}
function groupComponentsByType(components) {
const map = new Map();
for (const component of components) {
const typeName = component.type.name;
if (!map.has(typeName)) {
map.set(typeName, []);
}
map.get(typeName).push(component.fullName);
}
return map;
}
//# sourceMappingURL=mergePackageXmlFiles.js.map