UNPKG

salesforce-alm

Version:

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

169 lines (167 loc) 7.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SourceLocations = 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 util_1 = require("util"); const core_1 = require("@salesforce/core"); const kit_1 = require("@salesforce/kit"); const metadataTypeFactory_1 = require("./metadataTypeFactory"); const MetadataRegistry = require("./metadataRegistry"); const nonDecomposedElementsIndex_1 = require("./nonDecomposedElementsIndex"); /** * SourceLocations maintains 2 different indices: `filePathsIndex` and `metadataPathsIndex`. * * The `filePathsIndex` is a map of metadata keys to the file locations, e.g. * ``` * { * ApexClass__myClass: [~/workspace/my-project/classes/myClass.cls], * CustomObject__myObject__c.myField: [~/workspace/my-project/objects/myObject/fields/myField__c.field-meta.xml] * } * ``` * The `metadataPathsIndex` is a map of metadata keys to the meta file locations, e.g. * ``` * { * ApexClass__myClass: [~/workspace/my-project/classes/myClass.cls-meta.xml] * CustomObject__myObject__c: [~/workspace/my-project/objects/myObject/myObject__c.object-meta.xml] * } * ``` * The main difference between these two indices is that `filePathsIndex` contains entries for all workspace elements, * whereas the `metadataPathsIndex` ONLY contains the entries for the aggregate workspace elements. * * We allow multiple file paths per metadata key because the same metadata could live in multiple packages, e.g. CustomLabels. * When getting a file path based on a given key, we use SfdxProject.getActivePackage() to determine which path to return. * */ class SourceLocations extends kit_1.AsyncCreatable { constructor(options) { super(options); this.metadataRegistry = options.metadataRegistry; this.sourcePathInfos = options.sourcePathInfos; this.shouldBuildIndices = options.shouldBuildIndices; this.username = options.username; } async init() { this.logger = await core_1.Logger.child(this.constructor.name); // No need to build indices in some cases, e.g., mdapi:convert and source:convert if (this.shouldBuildIndices) { await this.buildIndices(); } } getMetadataPath(metadataType, fullName) { const key = MetadataRegistry.getMetadataKey(metadataType, fullName); const paths = SourceLocations.metadataPathsIndex.get(key); if (paths) { return this.getPathByActivePackage(paths); } else { this.logger.debug(`No metadata path found for ${key}`); } } addMetadataPath(metadataType, fullName, metadataPath) { const key = MetadataRegistry.getMetadataKey(metadataType, fullName); if (SourceLocations.metadataPathsIndex.has(key)) { const existing = SourceLocations.metadataPathsIndex.get(key); SourceLocations.metadataPathsIndex.set(key, existing.concat(metadataPath)); } else { SourceLocations.metadataPathsIndex.set(key, [metadataPath]); } } getFilePath(metadataType, fullName) { const key = MetadataRegistry.getMetadataKey(metadataType, fullName); // We search both indices since nondecomposed elements (e.g. CustomLabel) are not // included in the filePathsIndex let paths = SourceLocations.filePathsIndex.get(key); if (!paths && SourceLocations.nonDecomposedElementsIndex) { paths = [SourceLocations.nonDecomposedElementsIndex.getMetadataFilePath(key)]; } if (paths) { return this.getPathByActivePackage(paths); } else { this.logger.debug(`No file path found for ${key}`); } } addFilePath(pathMetadataType, sourcePath) { const aggregateMetadataType = pathMetadataType.getAggregateMetadataName(); const fullName = decodeURIComponent(pathMetadataType.getFullNameFromFilePath(sourcePath)); const key = MetadataRegistry.getMetadataKey(aggregateMetadataType, fullName); if (SourceLocations.filePathsIndex.has(key)) { const existing = SourceLocations.filePathsIndex.get(key); SourceLocations.filePathsIndex.set(key, existing.concat(sourcePath)); } else { SourceLocations.filePathsIndex.set(key, [sourcePath]); } } getPathByActivePackage(paths) { if (paths.length === 1) { return paths[0]; } const activePackage = core_1.SfdxProject.getInstance().getActivePackage(); const match = paths.find((p) => { const pkgName = core_1.SfdxProject.getInstance().getPackageNameFromPath(p); return pkgName === (activePackage && activePackage.name); }); return match || paths[0]; } async buildIndices() { SourceLocations._nonDecomposedElementsIndex = await nonDecomposedElementsIndex_1.NonDecomposedElementsIndex.getInstance({ username: this.username, metadataRegistry: this.metadataRegistry, }); for (const sourcePathInfo of this.sourcePathInfos) { const pathMetadataType = sourcePathInfo.metadataType ? metadataTypeFactory_1.MetadataTypeFactory.getMetadataTypeFromMetadataName(sourcePathInfo.metadataType, this.metadataRegistry) : null; if (pathMetadataType) { metadataTypeFactory_1.MetadataTypeCache.sourcePaths.set(sourcePathInfo.sourcePath, pathMetadataType); if (sourcePathInfo.isMetadataFile) { const aggregateFullName = pathMetadataType.getAggregateFullNameFromFilePath(sourcePathInfo.sourcePath); if (this.isInvalidPath(sourcePathInfo.sourcePath)) { throw new Error(`Invalid source path for metadataType: ${pathMetadataType}`); } if (SourceLocations.nonDecomposedElementsIndex.isNonDecomposedElement(sourcePathInfo.metadataType)) { await SourceLocations.nonDecomposedElementsIndex.handleDecomposedElements(sourcePathInfo); } const aggregateMetadataPath = pathMetadataType.getAggregateMetadataFilePathFromWorkspacePath(sourcePathInfo.sourcePath); this.addMetadataPath(pathMetadataType.getMetadataName(), aggregateFullName, aggregateMetadataPath); this.addFilePath(pathMetadataType, sourcePathInfo.sourcePath); } else if (!sourcePathInfo.isDirectory) { this.addFilePath(pathMetadataType, sourcePathInfo.sourcePath); } } } } isInvalidPath(sourcePath) { return kit_1.isEmpty(sourcePath) || !util_1.isString(sourcePath); } static get filePathsIndex() { return this._filePathsIndex; } static set filePathsIndex(newIndex) { this._filePathsIndex = newIndex; } static get metadataPathsIndex() { return this._metadataPathsIndex; } static set metadataPathsIndex(newIndex) { this._metadataPathsIndex = newIndex; } static get nonDecomposedElementsIndex() { return this._nonDecomposedElementsIndex; } static set nonDecomposedElementsIndex(newIndex) { this._nonDecomposedElementsIndex = newIndex; } } exports.SourceLocations = SourceLocations; SourceLocations._metadataPathsIndex = new Map(); SourceLocations._filePathsIndex = new Map(); //# sourceMappingURL=sourceLocations.js.map