UNPKG

@salesforce/source-tracking

Version:

API for tracking local and remote Salesforce metadata changes

114 lines 6.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registrySupportsType = exports.mappingsForSourceMemberTypesToMetadataType = exports.getMetadataKeyFromFileResponse = void 0; /* * Copyright 2025, Salesforce, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const node_path_1 = require("node:path"); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const lifecycle_1 = require("@salesforce/core/lifecycle"); const functions_1 = require("./functions"); // See UT for examples of the complexity this must handle // keys always use forward slashes, even on Windows const pathAfterFullName = (fileResponse) => fileResponse?.filePath ? (0, node_path_1.join)((0, node_path_1.dirname)(fileResponse.filePath).substring((0, node_path_1.dirname)(fileResponse.filePath).lastIndexOf(fileResponse.fullName)), (0, node_path_1.basename)(fileResponse.filePath)).replace(/\\/gi, '/') : ''; const registryAccess = new source_deploy_retrieve_1.RegistryAccess(); // only compute once const aliasTypes = registryAccess .getAliasTypes() // allow assertion because aliasTypes are defined as having that property .map((aliasType) => [aliasType.name, registryAccess.getTypeByName(aliasType.aliasFor).name]); const reverseAliasTypes = new Map(aliasTypes.map(([alias, type]) => [type, alias])); // handle all "weird" type/name translation between SourceMember and SDR FileResponse // These get de-duplicated in a set later, so it's ok to have one per file const getMetadataKeyFromFileResponse = (fileResponse) => { // also create an element for the parent object if (fileResponse.type === 'CustomField' && fileResponse.filePath) { const splits = (0, node_path_1.normalize)(fileResponse.filePath).split(node_path_1.sep); const objectFolderIndex = splits.indexOf('objects'); return [ (0, functions_1.getMetadataKey)('CustomObject', splits[objectFolderIndex + 1]), (0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName), ]; } // Aura/LWC need to have both the bundle level and file level keys if (fileResponse.type === 'LightningComponentBundle' && fileResponse.filePath) { return [ (0, functions_1.getMetadataKey)('LightningComponentResource', pathAfterFullName(fileResponse)), (0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName), ]; } if (fileResponse.type === 'AuraDefinitionBundle' && fileResponse.filePath) { return [ (0, functions_1.getMetadataKey)('AuraDefinition', pathAfterFullName(fileResponse)), (0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName), ]; } // CustomLabels (file) => CustomLabel[] (how they're stored in SourceMembers) if (fileResponse.type === 'CustomLabels' && fileResponse.filePath) { return source_deploy_retrieve_1.ComponentSet.fromSource(fileResponse.filePath) .getSourceComponents() .toArray() .flatMap((component) => component.getChildren().map((child) => (0, functions_1.getMetadataKey)('CustomLabel', child.fullName))); } // if we've aliased a type, we'll have to possibly sync both types--you can't tell from the sourceComponent retrieved which way it was stored on the server if (reverseAliasTypes.has(fileResponse.type)) { return [ (0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName), (0, functions_1.getMetadataKey)(reverseAliasTypes.get(fileResponse.type), fileResponse.fullName), ]; } // standard key for everything else return [(0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName)]; }; exports.getMetadataKeyFromFileResponse = getMetadataKeyFromFileResponse; exports.mappingsForSourceMemberTypesToMetadataType = new Map([ ...aliasTypes, ['AuraDefinition', 'AuraDefinitionBundle'], ['LightningComponentResource', 'LightningComponentBundle'], ]); const registrySupportsType = (registry = new source_deploy_retrieve_1.RegistryAccess()) => (type) => { if (exports.mappingsForSourceMemberTypesToMetadataType.has(type)) { return true; } if (type === 'PicklistValue') { /* "PicklistValue" appears occasionally in sourceMembers, but it's not a real, addressable type in the registry * It only appears when a picklist value is reactivated, so I'd call this a SourceMember bug * We also can't make it a child type in the SDR registry because it it can be a parent of either CustomField/Picklist OR GlobalValueSet * in both parent cases (GVS and CustomField), the the parent is marked as changed in SourceMembers, to the behavior is ok igoring the PicklistValue * This suppresses the warning, and could be removed if the SourceMember bug is fixed */ return false; } if (type === 'ExperienceResource') { /* ExperienceResource is a child of ExperienceBundle but fine-grained source tracking isn't supported for * ExperienceBundle since it's not defined that way in the SDR registry. Since ExperienceBundle is * essentially deprecated in favor of DigitalExperienceBundle this is not something we're going to support. */ return false; } try { // this must use getTypeByName because findType doesn't support addressable child types (ex: customField!) registry.getTypeByName(type); return true; } catch (e) { void lifecycle_1.Lifecycle.getInstance().emitWarning(`Unable to find type ${type} in registry`); return false; } }; exports.registrySupportsType = registrySupportsType; //# sourceMappingURL=metadataKeys.js.map