UNPKG

@salesforce/packaging

Version:

Packaging library for the Salesforce packaging platform

171 lines 8.49 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.retrievePackageVersionMetadata = retrievePackageVersionMetadata; /* * Copyright (c) 2023, 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 node_path_1 = __importDefault(require("node:path")); const node_fs_1 = __importDefault(require("node:fs")); const core_1 = require("@salesforce/core"); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const kit_1 = require("@salesforce/kit"); const packageUtils_1 = require("../utils/packageUtils"); const packageCreate_1 = require("./packageCreate"); const package_1 = require("./package"); const packageVersion_1 = require("./packageVersion"); core_1.Messages.importMessagesDirectory(__dirname); const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'package'); /** * Download the metadata files for a previously published package version, convert them to source format, and put them into a new project folder within the sfdx project. * * @param project * @param options {@link PackageVersionMetadataDownloadOptions} * @param connection * @returns */ async function retrievePackageVersionMetadata(project, options, connection) { // Validate the destination path is suitable to extract package version metadata (must be new or empty) const destinationFolder = options.destinationFolder ?? 'force-app'; if (node_path_1.default.isAbsolute(destinationFolder)) { throw messages.createError('sourcesDownloadDirectoryMustBeRelative'); } const destinationPath = node_path_1.default.join(project.getPath(), destinationFolder); if (!node_fs_1.default.existsSync(destinationPath)) { node_fs_1.default.mkdirSync(destinationPath, { recursive: true }); } if (!(0, packageUtils_1.isPackageDirectoryEffectivelyEmpty)(destinationPath)) { throw messages.createError('sourcesDownloadDirectoryNotEmpty'); } // Get the DeveloperUsePkgZip URL from the Package2Version record const subscriberPackageVersionId = project.getPackageIdFromAlias(options.subscriberPackageVersionId) ?? options.subscriberPackageVersionId; // Query Package2Version to get the record by SubscriberPackageVersionId const queryOptions = { whereClause: `WHERE SubscriberPackageVersionId = '${subscriberPackageVersionId}'`, }; let versionInfo; try { [versionInfo] = await packageVersion_1.PackageVersion.queryPackage2Version(connection, queryOptions); } catch (e) { const msg = e instanceof Error ? e.message : String(e); if (msg.includes("No such column 'DeveloperUsePkgZip' on entity 'Package2Version'")) { throw messages.createError('developerUsePkgZipFieldUnavailable'); } if (msg.includes("sObject type 'Package2Version' is not supported.")) { throw messages.createError('packagingNotEnabledOnOrg'); } throw e; } if (!versionInfo?.DeveloperUsePkgZip) { throw messages.createError('developerUsePkgZipFieldUnavailable'); } const responseBase64 = await connection.tooling.request(versionInfo.DeveloperUsePkgZip, { encoding: 'base64', }); const buffer = Buffer.from(responseBase64, 'base64'); let tree; try { tree = await source_deploy_retrieve_1.ZipTreeContainer.create(buffer); } catch (e) { if (e instanceof Error && e.message.includes('data length = 0')) { throw messages.createError('downloadDeveloperPackageZipHasNoData'); } throw e; } let dependencies = []; // 2GP packages declare their dependencies in dependency-ids.json within the outer zip. if (tree.exists('dependency-ids.json')) { const f = await tree.readFile('dependency-ids.json'); const idsObj = JSON.parse(f.toString()); if (idsObj?.ids) { dependencies = idsObj.ids; } } // 2GP packages have the package.zip wrapped in an outer zip. if (tree.exists('package.zip')) { tree = await source_deploy_retrieve_1.ZipTreeContainer.create(await tree.readFile('package.zip')); } const zipComponents = source_deploy_retrieve_1.ComponentSet.fromSource({ fsPaths: ['.'], tree, }) .getSourceComponents() .toArray(); const result = await new source_deploy_retrieve_1.MetadataConverter().convert(zipComponents, 'source', { type: 'directory', outputDirectory: destinationPath, genUniqueDir: false, }); await attemptToUpdateProjectJson(project, connection, versionInfo.Package2Id, subscriberPackageVersionId, dependencies, destinationFolder); return result; } /** * Attempt to update the sfdx-project.json file to add information about the retrieved sources. If this fails for some reason we * print out an error message and return so the user will still see a list of retrieved metadata. * */ async function attemptToUpdateProjectJson(project, connection, packageId, subscriberPackageVersionId, dependencyIds, destinationFolder) { const logger = core_1.Logger.childFromRoot('packageVersionRetrieve'); if (kit_1.env.getBoolean('SF_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_VERSION_RETRIEVE')) { logger.info('Skipping sfdx-project.json updates because SF_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_VERSION_RETRIEVE is set'); return; } try { const queryOptions = { whereClause: `WHERE SubscriberPackageVersionId = '${subscriberPackageVersionId}'`, }; const [version] = await packageVersion_1.PackageVersion.queryPackage2Version(connection, queryOptions); if (version) { const pkg = new package_1.Package({ packageAliasOrId: version.Package2Id, project, connection, }); const pkgData = await pkg.getPackageData(); if (pkgData) { const dirEntry = (0, packageCreate_1.createPackageDirEntry)(project, { name: pkgData.Name, description: pkgData.Description, path: destinationFolder, noNamespace: pkgData.NamespacePrefix != null, orgDependent: pkgData.IsOrgDependent, packageType: pkgData.ContainerOptions, errorNotificationUsername: pkgData.PackageErrorUsername, }); const namedDir = { ...dirEntry, versionNumber: '<set version number>', versionName: '<set version name>', ancestorVersion: '<set ancestor version>', dependencies: dependencyIds.map((dep) => ({ package: dep })), }; project.getSfProjectJson().addPackageDirectory(namedDir); const packageVersionVersionString = `${version.MajorVersion}.${version.MinorVersion}.${version.PatchVersion}-${version.BuildNumber}`; const [alias, writtenId] = await (0, packageUtils_1.generatePackageAliasEntry)(connection, project, subscriberPackageVersionId, packageVersionVersionString, 'main', pkg.getId()); project.getSfProjectJson().addPackageAlias(alias, writtenId); if (pkgData.ContainerOptions === 'Managed' && !project.getSfProjectJson().get('namespace')) { project.getSfProjectJson().set('namespace', pkgData.NamespacePrefix); } await project.getSfProjectJson().write(); } else { logger.warn(`Failed to update sfdx-project.json. Could not find package for ${version.Package2Id}. This should never happen.`); } } else { logger.info(`Could not find Package2Version record for ${subscriberPackageVersionId}. No updates to sfdx-project.json will be made.`); } } catch (e) { const msg = e instanceof Error ? e.message : e; logger.error(`Encountered error trying to update sfdx-project.json after retrieving package version metadata: ${msg}`); } } //# sourceMappingURL=packageVersionRetrieve.js.map