@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
235 lines • 25.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ProjectConfig_1 = __importDefault(require("../../project/ProjectConfig"));
const sfp_logger_1 = require("@flxbl-io/sfp-logger");
const sfp_logger_2 = __importStar(require("@flxbl-io/sfp-logger"));
const lodash_1 = __importDefault(require("lodash"));
const UserDefinedExternalDependency_1 = __importDefault(require("../../project/UserDefinedExternalDependency"));
const semver_1 = __importDefault(require("semver"));
class TransitiveDependencyResolver {
constructor(sfdxProjectConfig, logger) {
this.sfdxProjectConfig = sfdxProjectConfig;
this.logger = logger;
}
async resolveTransitiveDependencies() {
const result = await this.resolveTransitiveDependenciesWithDetails();
return result.resolvedDependencies;
}
async resolveTransitiveDependenciesWithDetails() {
sfp_logger_2.default.log('Validating Project Dependencies...', sfp_logger_2.LoggerLevel.INFO, this.logger);
let clonedProjectConfig = await lodash_1.default.cloneDeep(this.sfdxProjectConfig);
clonedProjectConfig = await new UserDefinedExternalDependency_1.default().cleanupEntries(clonedProjectConfig);
let pkgWithDependencies = ProjectConfig_1.default.getAllPackagesAndItsDependencies(clonedProjectConfig);
pkgWithDependencies = this.fillDepsWithUserDefinedExternalDependencyMap(pkgWithDependencies, new UserDefinedExternalDependency_1.default().fetchDependencyEntries(clonedProjectConfig));
// Track version contributors during resolution
const versionContributors = new Map();
const originalDeps = new Map(pkgWithDependencies);
pkgWithDependencies = this.fillDepsTransitively(pkgWithDependencies, versionContributors);
let sortedPackages = this.topologicalSort(pkgWithDependencies);
let sortedPkgWithDependencies = new Map();
sortedPackages.forEach(pkg => {
let dependencies = pkgWithDependencies.get(pkg) || [];
let uniqueDependencies = new Map();
dependencies.forEach(dep => {
const existing = uniqueDependencies.get(dep.package);
if (!existing || this.compareVersions(dep.versionNumber, existing.versionNumber) > 0) {
uniqueDependencies.set(dep.package, dep);
}
});
let sortedDependencies = Array.from(uniqueDependencies.values())
.sort((a, b) => sortedPackages.indexOf(a.package) - sortedPackages.indexOf(b.package));
sortedPkgWithDependencies.set(pkg, sortedDependencies);
});
// Generate and log dependency details
const details = this.generateDependencyDetails(sortedPackages, sortedPkgWithDependencies, originalDeps, versionContributors);
return {
resolvedDependencies: sortedPkgWithDependencies,
details
};
}
compareVersions(version1, version2) {
if (!version1 && !version2)
return 0;
if (!version1)
return -1;
if (!version2)
return 1;
// Handle LATEST/NEXT suffixes
const v1HasLatest = version1.endsWith('.LATEST');
const v2HasLatest = version2.endsWith('.LATEST');
const v1HasNext = version1.endsWith('.NEXT');
const v2HasNext = version2.endsWith('.NEXT');
// If one has LATEST and other doesn't, LATEST wins
if ((v1HasLatest || v1HasNext) && !v2HasLatest && !v2HasNext)
return 1;
if ((v2HasLatest || v2HasNext) && !v1HasLatest && !v1HasNext)
return -1;
// Extract base version (removing LATEST/NEXT if present)
const v1Base = version1.replace(/\.(LATEST|NEXT)$/, '');
const v2Base = version2.replace(/\.(LATEST|NEXT)$/, '');
// Split into version parts
const v1Parts = v1Base.split('.');
const v2Parts = v2Base.split('.');
// Compare first three parts using semver
const v1Semver = v1Parts.slice(0, 3).join('.');
const v2Semver = v2Parts.slice(0, 3).join('.');
const semverCompare = semver_1.default.compare(semver_1.default.coerce(v1Semver) || '0.0.0', semver_1.default.coerce(v2Semver) || '0.0.0');
if (semverCompare !== 0)
return semverCompare;
// If semver parts are equal, compare build numbers (4th part)
const buildNum1 = parseInt(v1Parts[3] || '0');
const buildNum2 = parseInt(v2Parts[3] || '0');
return buildNum1 - buildNum2;
}
fillDepsWithUserDefinedExternalDependencyMap(pkgWithDependencies, externalDependencyMap) {
if (externalDependencyMap) {
for (let pkg of Object.keys(externalDependencyMap)) {
pkgWithDependencies.set(pkg, externalDependencyMap[pkg]);
}
}
return pkgWithDependencies;
}
generateDependencyDetails(sortedPackages, resolvedDeps, originalDeps, versionContributors) {
const details = new Map();
sortedPackages.forEach(pkg => {
const dependencies = resolvedDeps.get(pkg) || [];
if (dependencies.length > 0) {
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_HEADER)(`\nPackage: ${pkg}`), sfp_logger_2.LoggerLevel.INFO, this.logger);
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_HEADER)('----------------------------------------'), sfp_logger_2.LoggerLevel.INFO, this.logger);
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_HEADER)('Dependencies:'), sfp_logger_2.LoggerLevel.INFO, this.logger);
const pkgDetails = {};
dependencies.forEach(dep => {
const isDirect = originalDeps.get(pkg)?.some(d => d.package === dep.package && d.versionNumber === dep.versionNumber) || false;
const contributorsSet = versionContributors.get(dep.package)?.get(dep.versionNumber || '') || new Set();
const contributors = Array.from(contributorsSet);
let message = `${dep.package}@${dep.versionNumber || 'unknown'}`;
if (isDirect) {
message += ' (direct dependency)';
}
else if (contributors.length > 0) {
message += ` (via ${contributors.join(', ')})`;
}
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_KEY_MESSAGE)(` ${message}`), sfp_logger_2.LoggerLevel.INFO, this.logger);
pkgDetails[dep.package] = {
version: dep.versionNumber || 'unknown',
isDirect,
contributors
};
});
details.set(pkg, pkgDetails);
}
});
return details;
}
fillDepsTransitively(pkgWithDependencies, versionContributors) {
let dependencyMap = new Map(pkgWithDependencies);
const resolveDependencies = (pkg, chain = new Set()) => {
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_HEADER)(`fetching dependencies for package:`) + (0, sfp_logger_1.COLOR_KEY_MESSAGE)(pkg), sfp_logger_2.LoggerLevel.TRACE, this.logger);
if (chain.has(pkg)) {
const circularChain = Array.from(chain).join(' -> ');
const errorMessage = `Circular dependency detected: ${circularChain} -> ${pkg}. Salesforce does not support circular dependencies between packages.`;
sfp_logger_2.default.log((0, sfp_logger_1.COLOR_ERROR)(errorMessage), sfp_logger_2.LoggerLevel.ERROR, this.logger);
throw new Error(errorMessage);
}
chain.add(pkg);
let dependencies = dependencyMap.get(pkg) || [];
let allDependencies = new Map();
// Add direct dependencies
dependencies.forEach(dep => {
const existing = allDependencies.get(dep.package);
if (!existing || this.compareVersions(dep.versionNumber, existing.versionNumber) > 0) {
allDependencies.set(dep.package, dep);
// Track version contributor
if (!versionContributors.has(dep.package)) {
versionContributors.set(dep.package, new Map());
}
const packageVersions = versionContributors.get(dep.package);
if (!packageVersions.has(dep.versionNumber || '')) {
packageVersions.set(dep.versionNumber || '', new Set());
}
packageVersions.get(dep.versionNumber || '').add(pkg);
}
});
// Add transitive dependencies
dependencies.forEach(dep => {
if (dependencyMap.has(dep.package)) {
let transitiveDeps = resolveDependencies(dep.package, new Set(chain));
transitiveDeps.forEach(td => {
const existing = allDependencies.get(td.package);
if (!existing || this.compareVersions(td.versionNumber, existing.versionNumber) > 0) {
allDependencies.set(td.package, td);
// Track version contributor
if (!versionContributors.has(td.package)) {
versionContributors.set(td.package, new Map());
}
const packageVersions = versionContributors.get(td.package);
if (!packageVersions.has(td.versionNumber || '')) {
packageVersions.set(td.versionNumber || '', new Set());
}
packageVersions.get(td.versionNumber || '').add(dep.package);
}
});
}
});
chain.delete(pkg);
return Array.from(allDependencies.values());
};
for (let pkg of dependencyMap.keys()) {
let resolvedDeps = resolveDependencies(pkg);
dependencyMap.set(pkg, resolvedDeps);
}
return dependencyMap;
}
swapAndDropArrayElement(arr, i, j) {
if (i < 0 || i >= arr.length || j < 0 || j >= arr.length) {
return arr;
}
let newArr = [...arr];
[newArr[i], newArr[j]] = [newArr[j], newArr[i]];
return [...newArr.slice(0, j), ...newArr.slice(j + 1)];
}
topologicalSort(pkgWithDependencies) {
let visited = new Set();
let result = [];
const visit = (pkg) => {
if (!visited.has(pkg)) {
visited.add(pkg);
let dependencies = pkgWithDependencies.get(pkg) || [];
dependencies.forEach(dep => visit(dep.package));
result.push(pkg);
}
};
for (let pkg of pkgWithDependencies.keys()) {
visit(pkg);
}
return result;
}
}
exports.default = TransitiveDependencyResolver;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNpdGl2ZURlcGVuZGVuY3lSZXNvbHZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3BhY2thZ2UvZGVwZW5kZW5jaWVzL1RyYW5zaXRpdmVEZXBlbmRlbmN5UmVzb2x2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGdGQUF3RDtBQUN4RCxxREFBbUc7QUFDbkcsbUVBQXNFO0FBQ3RFLG9EQUF1QjtBQUN2QixnSEFBMkY7QUFDM0Ysb0RBQTRCO0FBYTVCLE1BQXFCLDRCQUE0QjtJQUM3QyxZQUFvQixpQkFBc0IsRUFBVSxNQUFlO1FBQS9DLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBSztRQUFVLFdBQU0sR0FBTixNQUFNLENBQVM7SUFBRyxDQUFDO0lBRWhFLEtBQUssQ0FBQyw2QkFBNkI7UUFDdEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsd0NBQXdDLEVBQUUsQ0FBQztRQUNyRSxPQUFPLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztJQUN2QyxDQUFDO0lBRU0sS0FBSyxDQUFDLHdDQUF3QztRQUNqRCxvQkFBUyxDQUFDLEdBQUcsQ0FBQyxvQ0FBb0MsRUFBRSx3QkFBVyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkYsSUFBSSxtQkFBbUIsR0FBRyxNQUFNLGdCQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3BFLG1CQUFtQixHQUFHLE1BQU0sSUFBSSx1Q0FBZ0MsRUFBRSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3ZHLElBQUksbUJBQW1CLEdBQUcsdUJBQWEsQ0FBQyxnQ0FBZ0MsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzlGLG1CQUFtQixHQUFHLElBQUksQ0FBQyw0Q0FBNEMsQ0FDbkUsbUJBQW1CLEVBQ25CLElBQUksdUNB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