import { MetadataType } from '../salesforce/metadataClient';
export interface PackageManifest {
types: PackageType[];
version: string;
}
export interface PackageType {
name: string;
members: string[];
}
export class PackageXmlGenerator {
private static readonly DEFAULT_API_VERSION = '59.0';
static generatePackageXml(manifest: PackageManifest): string {
const types = manifest.types.map(type =>
` <types>
${type.members.map(member => `<members>${member}</members>`).join('\n ')}
<name>${type.name}</name>
</types>`
).join('\n');
return `<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
${types}
<version>${manifest.version}</version>
</Package>`;
}
static createManifestForMetadataTypes(metadataTypes: string[], version: string = PackageXmlGenerator.DEFAULT_API_VERSION): PackageManifest {
const types: PackageType[] = metadataTypes.map(type => ({
name: type,
members: ['*'] // Wildcard to retrieve all components of this type
}));
return {
types,
version
};
}
static createManifestForSpecificComponents(components: { type: string; names: string[] }[], version: string = PackageXmlGenerator.DEFAULT_API_VERSION): PackageManifest {
const types: PackageType[] = components.map(component => ({
name: component.type,
members: component.names
}));
return {
types,
version
};
}
static createManifestFromMetadataInfo(metadataItems: { type: string; fullName: string }[], version: string = PackageXmlGenerator.DEFAULT_API_VERSION): PackageManifest {
// Group by type
const typeMap = new Map<string, string[]>();
metadataItems.forEach(item => {
if (!typeMap.has(item.type)) {
typeMap.set(item.type, []);
}
typeMap.get(item.type)!.push(item.fullName);
});
const types: PackageType[] = Array.from(typeMap.entries()).map(([typeName, members]) => ({
name: typeName,
members: members.sort() // Sort for consistency
}));
return {
types,
version
};
}
// Common metadata types for easy reference
static readonly COMMON_METADATA_TYPES = {
APEX_CLASSES: 'ApexClass',
APEX_TRIGGERS: 'ApexTrigger',
CUSTOM_OBJECTS: 'CustomObject',
CUSTOM_FIELDS: 'CustomField',
LAYOUTS: 'Layout',
FLOWS: 'Flow',
VALIDATION_RULES: 'ValidationRule',
PROFILES: 'Profile',
PERMISSION_SETS: 'PermissionSet',
CUSTOM_TABS: 'CustomTab',
APEX_PAGES: 'ApexPage',
APEX_COMPONENTS: 'ApexComponent'
} as const;
// Generate common package manifests
static createApexManifest(version?: string): PackageManifest {
return this.createManifestForMetadataTypes([
this.COMMON_METADATA_TYPES.APEX_CLASSES,
this.COMMON_METADATA_TYPES.APEX_TRIGGERS
], version);
}
static createCustomObjectManifest(version?: string): PackageManifest {
return this.createManifestForMetadataTypes([
this.COMMON_METADATA_TYPES.CUSTOM_OBJECTS,
this.COMMON_METADATA_TYPES.CUSTOM_FIELDS
], version);
}
static createLayoutsAndFlowsManifest(version?: string): PackageManifest {
return this.createManifestForMetadataTypes([
this.COMMON_METADATA_TYPES.LAYOUTS,
this.COMMON_METADATA_TYPES.FLOWS
], version);
}
static createSecurityManifest(version?: string): PackageManifest {
return this.createManifestForMetadataTypes([
this.COMMON_METADATA_TYPES.PROFILES,
this.COMMON_METADATA_TYPES.PERMISSION_SETS,
this.COMMON_METADATA_TYPES.VALIDATION_RULES
], version);
}
}