UNPKG

salesforce-alm

Version:

This package contains tools, and APIs, for an improved salesforce.com developer experience.

204 lines (202 loc) 8.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AggregateSourceElements = void 0; /* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ const aggregateSourceElement_1 = require("./aggregateSourceElement"); const nonDecomposedElementsIndex_1 = require("./nonDecomposedElementsIndex"); class AggregateSourceElements extends Map { constructor(entries) { super(entries); } /** * DO NOT USE. Use getSourceElement instead. * Returns the FIRST matching AggregateSourceElement. We should not use this method * because you're not guaranteed to get the source element from the correct package. */ findSourceElementByKey(key) { let returnValue; this.forEach((aggregateSourceElements) => { if (aggregateSourceElements.has(key)) { returnValue = aggregateSourceElements.get(key); } }); return returnValue; } /** * Returns `AggregateSourceElements` from all package directories matching the * given source element key. * * @param key a metadata type name pair. E.g., ApexClass__MyClass * @param options the filter options to apply when matching AggregateSourceElements */ filterSourceElementsByKey(key, options = {}) { const filteredElements = new AggregateSourceElements(); this.forEach((aseMap) => { if (options.fuzzy) { const [fuzzyMdType, mdName = ''] = key.split('__'); aseMap.forEach((ase, aseKey) => { let [type, name] = aseKey.split('__'); name = mdName === '' ? '' : name; // This ASE matches if: // 1. The metadata type fuzzy matches *AND* // 2. The metadata type is "CustomLabel" and belongs to this ASE *OR* // 3. The metadata names are the same if (type.includes(fuzzyMdType)) { if (fuzzyMdType === 'CustomLabel' && name !== '') { // Special handling for an individual CustomLabel. // Must find it within the labels source file to match. const sourcePath = ase.getMetadataFilePath(); if (nonDecomposedElementsIndex_1.NonDecomposedElementsIndex.belongsTo(sourcePath, `CustomLabels__${mdName}`)) { filteredElements.setIn(ase.getPackageName(), aseKey, ase); } } else if (name === mdName) { filteredElements.setIn(ase.getPackageName(), aseKey, ase); } } }); } else { if (aseMap.has(key)) { const ase = aseMap.get(key); filteredElements.setIn(ase.getPackageName(), ase.getKey(), ase); } } }); return filteredElements; } /** * Attempts to find the parent AggregateSourceElement across package directories * that contains the matching child metadata type and name as a WorkspaceElement. * It then returns the parent ASE with all WorkspaceElements removed except for * the matching child WorkspaceElement. This allows fine-grained deploys/retrieves. * * E.g., Given the custom field "FieldA" that belongs to custom object "CO1"; * - CO1 has meta-xml file and "FieldB" in package directory X * - CO1 also has "FieldA" and "FieldC" in package directory Y * This method will return the "CO1" ASE from package dir Y containing * only the "FieldA" WorkspaceElement. */ findParentElement(parentKey, childType, childName) { let returnValue; // debug(`finding parent element: ${parentKey} containing child: ${childKey}`); this.forEach((aggregateSourceElements) => { if (aggregateSourceElements.has(parentKey)) { const ase = aggregateSourceElements.get(parentKey); if (childType && childName) { let matchingWorkspaceElement; // Match the childType and childName with the workspace elements const matchFound = ase.getWorkspaceElements().some((we) => { if (we.getFullName() === childName && we.getMetadataName() === childType) { matchingWorkspaceElement = we; return true; } return false; }); if (matchFound) { // debug('Found matching source element:', matchingWorkspaceElement.toObject(), 'in package:', ase.getPackageName()); // Clone the ASE so as not to mutate, then set the workspace elements // for the cloned ASE to be the one matched. const clonedAse = new aggregateSourceElement_1.AggregateSourceElement(ase.getMetadataType(), ase.getAggregateFullName(), ase.getMetadataFilePath(), ase.metadataRegistry); clonedAse.workspaceElements = [matchingWorkspaceElement]; returnValue = clonedAse; } } } }); return returnValue; } getSourceElement(packageName, key) { if (this.has(packageName)) { return this.get(packageName).get(key); } } deleteSourceElement(packageName, key) { if (this.has(packageName)) { this.get(packageName).delete(key); } return this; } setIn(packageName, sourceElementKey, sourceElement) { if (this.has(packageName)) { this.get(packageName).set(sourceElementKey, sourceElement); } else { this.set(packageName, new Map().set(sourceElementKey, sourceElement)); } return this; } /** * Returns a flat array of all source elements across all packages */ getAllSourceElements() { let elements = []; this.forEach((sourceElements) => { elements = elements.concat([...sourceElements.values()]); }); return elements; } getAllWorkspaceElements() { let elements = []; this.forEach((sourceElements) => { [...sourceElements.values()].forEach((el) => { elements = elements.concat(el.workspaceElements); }); }); return elements; } getAllSourceKeys() { let keys = []; this.forEach((sourceElements) => { keys = keys.concat([...sourceElements.keys()]); }); return keys; } isEmpty() { return this.size === 0; } /** * Merges `AggregateSourceElements` and their corresponding `WorkspaceElements` with their * corresponding package directory names. * Note that 2 `AggregateSourceElements` with identical `AggregateSourceElement` key entries * (i.e., same CustomObject) but with different `WorkspaceElements` will simply add all * missing `WorkspaceElements` from the merging ASE to the existing ASE. * * @param aggregateSourceElements The other `AggregateSourceElements` to merge with this one. */ merge(aggregateSourceElements) { aggregateSourceElements.forEach((aseMap, packageName) => { if (this.has(packageName)) { const elements = this.get(packageName); aseMap.forEach((ase, key) => { const existingAse = elements.get(key); if (existingAse) { // Both AggregateSourceElements have an ASE key in the same package, // so add any missing WorkspaceElements from the merging ASE // to the existing ASE. const weFullNames = existingAse.getWorkspaceElements().map((we) => we.getFullName()); ase.getWorkspaceElements().forEach((we) => { if (!weFullNames.includes(we.getFullName())) { existingAse.addWorkspaceElement(we); } }); } else { elements.set(key, ase); } }); } else { this.set(packageName, aseMap); } }); return this; } } exports.AggregateSourceElements = AggregateSourceElements; //# sourceMappingURL=aggregateSourceElements.js.map