@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
191 lines • 19.2 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sfp_logger_1 = __importDefault(require("@flxbl-io/sfp-logger"));
const core_1 = require("@salesforce/core");
const PoolBaseImpl_1 = require("./PoolBaseImpl");
const GetUserEmail_1 = require("./services/fetchers/GetUserEmail");
const ScratchOrgInfoFetcher_1 = __importDefault(require("./services/fetchers/ScratchOrgInfoFetcher"));
const ScratchOrgInfoAssigner_1 = __importDefault(require("./services/updaters/ScratchOrgInfoAssigner"));
const ClientSourceTracking_1 = __importDefault(require("./ClientSourceTracking"));
const IsValidSfdxAuthUrl_1 = __importDefault(require("./prequisitecheck/IsValidSfdxAuthUrl"));
const ScratchOrgOperator_1 = __importDefault(require("../ScratchOrgOperator"));
class PoolFetchImpl extends PoolBaseImpl_1.PoolBaseImpl {
constructor(hubOrg, tag, mypool, authURLEnabledScratchOrg, sendToUser, alias, setdefaultusername, fetchAllScratchOrgs, limitBy) {
super(hubOrg);
this.fetchAllScratchOrgs = fetchAllScratchOrgs;
this.limitBy = limitBy;
this.isSourceTrackingToBeSet = false;
this.tag = tag;
this.mypool = mypool;
this.authURLEnabledScratchOrg = authURLEnabledScratchOrg;
this.sendToUser = sendToUser;
this.alias = alias;
this.setdefaultusername = setdefaultusername;
}
setSourceTrackingOnFetch() {
this.isSourceTrackingToBeSet = true;
}
async onExec() {
const results = (await new ScratchOrgInfoFetcher_1.default(this.hubOrg).getScratchOrgsByTag(this.tag, this.mypool, true));
let availableSo = [];
if (results.records.length > 0) {
availableSo = results.records.filter((soInfo) => soInfo.Allocation_status__c === 'Available');
}
if (availableSo.length == 0) {
throw new Error(`No scratch org available at the moment for ${this.tag}, try again in sometime.`);
}
if (this.fetchAllScratchOrgs) {
return this.fetchAllScratchOrg(availableSo, this.limitBy);
}
else
return this.fetchSingleScratchOrg(availableSo);
}
async fetchAllScratchOrg(availableSo, limitBy) {
let fetchedSOs = [];
if (availableSo.length > 0) {
sfp_logger_1.default.log(`${this.tag} pool has ${availableSo.length} Scratch orgs available`, core_1.LoggerLevel.TRACE);
let count = 1;
for (let element of availableSo) {
if (this.authURLEnabledScratchOrg) {
if (element.SfdxAuthUrl__c && !(0, IsValidSfdxAuthUrl_1.default)(element.SfdxAuthUrl__c)) {
sfp_logger_1.default.log(`Iterating through pool to find a scratch org with valid authURL`, core_1.LoggerLevel.TRACE);
continue;
}
}
sfp_logger_1.default.log(`Scratch org ${element.SignupUsername} is allocated from the pool. Expiry date is ${element.ExpirationDate}`, core_1.LoggerLevel.TRACE);
let soDetail = {};
soDetail['Id'] = element.Id;
soDetail.orgId = element.ScratchOrg;
soDetail.loginURL = element.LoginUrl;
soDetail.username = element.SignupUsername;
soDetail.password = element.Password__c;
soDetail.expiryDate = element.ExpirationDate;
soDetail.sfdxAuthUrl = element.SfdxAuthUrl__c;
soDetail.status = 'Available';
soDetail.alias = `SO` + count;
fetchedSOs.push(soDetail);
if (limitBy && count == limitBy)
break;
count++;
}
}
for (const soDetail of fetchedSOs) {
//Login to the org
let isLoginSuccessFull = await this.loginToScratchOrgIfSfdxAuthURLExists(soDetail);
if (!isLoginSuccessFull) {
sfp_logger_1.default.log(`Unable to login to scratchorg ${soDetail.username}}`, core_1.LoggerLevel.ERROR);
fetchedSOs = fetchedSOs.filter((item) => item.username !== soDetail.username);
}
}
return fetchedSOs;
}
async fetchSingleScratchOrg(availableSo) {
let soDetail;
if (availableSo.length > 0) {
sfp_logger_1.default.log(`${this.tag} pool has ${availableSo.length} Scratch orgs available`, core_1.LoggerLevel.TRACE);
for (let element of availableSo) {
if (this.authURLEnabledScratchOrg) {
if (element.SfdxAuthUrl__c && !(0, IsValidSfdxAuthUrl_1.default)(element.SfdxAuthUrl__c)) {
sfp_logger_1.default.log(`Iterating through pool to find a scratch org with valid authURL`, core_1.LoggerLevel.TRACE);
continue;
}
}
let allocateSO = await new ScratchOrgInfoAssigner_1.default(this.hubOrg).setScratchOrgInfo({
Id: element.Id,
Allocation_status__c: 'Allocate',
});
if (allocateSO === true) {
sfp_logger_1.default.log(`Scratch org ${element.SignupUsername} is allocated from the pool. Expiry date is ${element.ExpirationDate}`, core_1.LoggerLevel.TRACE);
soDetail = {};
soDetail['Id'] = element.Id;
soDetail.orgId = element.ScratchOrg;
soDetail.loginURL = element.LoginUrl;
soDetail.username = element.SignupUsername;
soDetail.password = element.Password__c;
soDetail.expiryDate = element.ExpirationDate;
soDetail.sfdxAuthUrl = element.SfdxAuthUrl__c;
soDetail.status = 'Assigned';
break;
}
else {
sfp_logger_1.default.log(`Scratch org ${element.SignupUsername} allocation failed. trying to get another Scratch org from ${this.tag} pool`, core_1.LoggerLevel.TRACE);
}
}
}
if (availableSo.length == 0 || !soDetail) {
throw new Error(`No scratch org available at the moment for ${this.tag}, try again in sometime.`);
}
if (this.sendToUser) {
//Fetch the email for user id
let emailId;
try {
emailId = await (0, GetUserEmail_1.getUserEmail)(this.sendToUser, this.hubOrg);
}
catch (error) {
sfp_logger_1.default.log('Unable to fetch details of the specified user, Check whether the user exists in the org ', core_1.LoggerLevel.ERROR);
throw new Error('Failed to fetch user details');
}
try {
//Send an email for username
await new ScratchOrgOperator_1.default(this.hubOrg).shareScratchOrgThroughEmail(emailId, soDetail);
}
catch (error) {
sfp_logger_1.default.log('Unable to send the scratchorg details to specified user. Check whether the user exists in the org', core_1.LoggerLevel.ERROR);
throw new Error('Unable to send the scratchorg details to specified user. Check whether the user exists in the org');
}
}
else {
//Login to the org
let isLoginSuccessFull = await this.loginToScratchOrgIfSfdxAuthURLExists(soDetail);
//Attempt to Fetch Source Tracking Files and silently continue if it fails
if (isLoginSuccessFull && this.isSourceTrackingToBeSet) {
try {
const conn = (await core_1.Org.create({ aliasOrUsername: soDetail.username })).getConnection();
const clientSourceTracking = await ClientSourceTracking_1.default.create(conn, null);
await clientSourceTracking.creatSourceTrackingFiles();
}
catch (error) {
sfp_logger_1.default.log('Retriveing Source Tracking skipped.. ' + error.message, core_1.LoggerLevel.TRACE);
}
}
}
return soDetail;
}
async loginToScratchOrgIfSfdxAuthURLExists(soDetail) {
try {
if (soDetail.sfdxAuthUrl && (0, IsValidSfdxAuthUrl_1.default)(soDetail.sfdxAuthUrl)) {
const oauth2Options = core_1.AuthInfo.parseSfdxAuthUrl(soDetail.sfdxAuthUrl);
const authInfo = await core_1.AuthInfo.create({ oauth2Options });
await authInfo.save({
...authInfo.getFields(),
isScratch: true,
devHubUsername: this.hubOrg.getUsername(),
expirationDate: soDetail.expiryDate,
password: soDetail.password
});
await authInfo.handleAliasAndDefaultSettings({
alias: this.alias ? this.alias : soDetail.alias,
setDefault: true,
setDefaultDevHub: false,
});
//https://github.com/salesforcecli/plugin-auth/blob/main/src/commands/org/login/sfdx-url.ts
const result = { clientSecret: '', ...authInfo.getFields(true) };
await core_1.AuthInfo.identifyPossibleScratchOrgs(result, authInfo);
return true;
}
else {
sfp_logger_1.default.log('Unable to autenticate to the scratch org', core_1.LoggerLevel.INFO);
return false;
}
}
catch (error) {
sfp_logger_1.default.log('Unable to autenticate to the scratch org due ' + error.message, core_1.LoggerLevel.ERROR);
return false;
}
}
}
exports.default = PoolFetchImpl;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9vbEZldGNoSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3NjcmF0Y2hvcmcvcG9vbC9Qb29sRmV0Y2hJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsc0VBQTZDO0FBQzdDLDJDQUE4RDtBQUM5RCxpREFBOEM7QUFFOUMsbUVBQWdFO0FBQ2hFLHNHQUE4RTtBQUM5RSx3R0FBZ0Y7QUFDaEYsa0ZBQTBEO0FBQzFELDhGQUFzRTtBQUN0RSwrRUFBdUQ7QUFFdkQsTUFBcUIsYUFBYyxTQUFRLDJCQUFZO0lBU25ELFlBQ0ksTUFBVyxFQUNYLEdBQVcsRUFDWCxNQUFlLEVBQ2Ysd0JBQWlDLEVBQ2pDLFVBQW1CLEVBQ25CLEtBQWMsRUFDZCxrQkFBNEIsRUFDcEIsbUJBQTZCLEVBQzdCLE9BQWU7UUFFdkIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBSE4sd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFVO1FBQzdCLFlBQU8sR0FBUCxPQUFPLENBQVE7UUFYbkIsNEJBQXVCLEdBQVksS0FBSyxDQUFDO1FBYzdDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLHdCQUF3QixHQUFHLHdCQUF3QixDQUFDO1FBQ3pELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztJQUNqRCxDQUFDO0lBRU0sd0JBQXdCO1FBQzNCLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUM7SUFDeEMsQ0FBQztJQUVTLEtBQUssQ0FBQyxNQUFNO1FBQ2xCLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxJQUFJLCtCQUFxQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMs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